Ejemplo n.º 1
2
func GetProcessNameMap() map[uint32]string {
	defer metrics("GetProcessNameMap")(time.Now())
	snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
	if err != nil {
		common.Error("Fail to syscall CreateToolhelp32Snapshot: %v", err)
		return nil
	}
	defer syscall.CloseHandle(snapshot)
	var procEntry syscall.ProcessEntry32
	procEntry.Size = uint32(unsafe.Sizeof(procEntry))
	if err = syscall.Process32First(snapshot, &procEntry); err != nil {
		common.Error("Fail to syscall Process32First: %v", err)
		return nil
	}
	processNameMap := make(map[uint32]string)
	for {
		processNameMap[procEntry.ProcessID] = parseProcessName(procEntry.ExeFile)
		if err = syscall.Process32Next(snapshot, &procEntry); err != nil {
			if err == syscall.ERROR_NO_MORE_FILES {
				return processNameMap
			}
			common.Error("Fail to syscall Process32Next: %v", err)
			return nil
		}
	}
}
Ejemplo n.º 2
1
// mmap memory maps a DB's data file.
// Based on: https://github.com/edsrzf/mmap-go
func mmap(db *DB, sz int) error {
	if !db.readOnly {
		// Truncate the database to the size of the mmap.
		if err := db.file.Truncate(int64(sz)); err != nil {
			return fmt.Errorf("truncate: %s", err)
		}
	}

	// Open a file mapping handle.
	sizelo := uint32(sz >> 32)
	sizehi := uint32(sz) & 0xffffffff
	h, errno := syscall.CreateFileMapping(syscall.Handle(db.file.Fd()), nil, syscall.PAGE_READONLY, sizelo, sizehi, nil)
	if h == 0 {
		return os.NewSyscallError("CreateFileMapping", errno)
	}

	// Create the memory map.
	addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, uintptr(sz))
	if addr == 0 {
		return os.NewSyscallError("MapViewOfFile", errno)
	}

	// Close mapping handle.
	if err := syscall.CloseHandle(syscall.Handle(h)); err != nil {
		return os.NewSyscallError("CloseHandle", err)
	}

	// Convert to a byte array.
	db.data = ((*[maxMapSize]byte)(unsafe.Pointer(addr)))
	db.datasz = sz

	return nil
}
Ejemplo n.º 3
0
func (sub *Subprocess) BottomHalf(d *SubprocessData, sig chan *SubprocessResult) {
	hProcess := d.platformData.hProcess
	hJob := d.platformData.hJob
	result := &SubprocessResult{}
	var waitResult uint32
	waitResult = syscall.WAIT_TIMEOUT

	var runState runningState

	for result.SuccessCode == 0 && waitResult == syscall.WAIT_TIMEOUT {
		waitResult, _ = syscall.WaitForSingleObject(hProcess, uint32(sub.TimeQuantum.Nanoseconds()/1000000))
		if waitResult != syscall.WAIT_TIMEOUT {
			break
		}

		_ = UpdateProcessTimes(&d.platformData, result, false)
		if sub.MemoryLimit > 0 {
			UpdateProcessMemory(&d.platformData, result)
		}

		runState.Update(sub, result)
	}

	switch waitResult {
	case syscall.WAIT_OBJECT_0:
		_ = syscall.GetExitCodeProcess(hProcess, &result.ExitCode)

	case syscall.WAIT_TIMEOUT:
		for waitResult == syscall.WAIT_TIMEOUT {
			syscall.TerminateProcess(hProcess, 0)
			waitResult, _ = syscall.WaitForSingleObject(hProcess, 100)
		}
	}

	_ = UpdateProcessTimes(&d.platformData, result, true)
	UpdateProcessMemory(&d.platformData, result)

	syscall.CloseHandle(hProcess)
	if hJob != syscall.InvalidHandle {
		syscall.CloseHandle(hJob)
	}

	sub.SetPostLimits(result)
	for _ = range d.startAfterStart {
		err := <-d.bufferChan
		if err != nil {
			log.Error(err)
		}
	}

	if d.stdOut.Len() > 0 {
		result.Output = d.stdOut.Bytes()
	}
	if d.stdErr.Len() > 0 {
		result.Error = d.stdErr.Bytes()
	}

	sig <- result
}
Ejemplo n.º 4
0
func (d *PlatformData) terminateAndClose() (err error) {
	if err = terminateProcessLoop(d.hProcess); err != nil {
		return
	}
	syscall.CloseHandle(d.hThread)
	syscall.CloseHandle(d.hProcess)
	return
}
Ejemplo n.º 5
0
func RunAndCollectSysStats(cmd *exec.Cmd, res *Result, N uint64, prefix string) (string, error) {
	initJobOnce.Do(initJob)

	childMu.Lock()
	children := childProcesses
	childProcesses = []syscall.Handle{}
	childMu.Unlock()
	for _, proc := range children {
		syscall.CloseHandle(proc)
	}

	var out bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &out
	t0 := time.Now()
	if err := cmd.Run(); err != nil {
		return out.String(), err
	}
	t1 := time.Now()

	res.RunTime = uint64(t1.Sub(t0)) / N
	res.Metrics[prefix+"time"] = res.RunTime

	childMu.Lock()
	children = childProcesses
	childProcesses = []syscall.Handle{}
	childMu.Unlock()
	if len(children) == 0 {
		log.Printf("sysStats.Collect: no child processes?")
		return out.String(), nil
	}
	defer func() {
		for _, proc := range children {
			syscall.CloseHandle(proc)
		}
	}()
	cputime := uint64(0)
	rss := uint64(0)
	for _, proc := range children {
		var Mem PROCESS_MEMORY_COUNTERS
		if err := getProcessMemoryInfo(proc, &Mem); err != nil {
			log.Printf("GetProcessMemoryInfo failed: %v", err)
			return out.String(), nil
		}
		var CPU syscall.Rusage
		if err := syscall.GetProcessTimes(proc, &CPU.CreationTime, &CPU.ExitTime, &CPU.KernelTime, &CPU.UserTime); err != nil {
			log.Printf("GetProcessTimes failed: %v", err)
			return out.String(), nil
		}
		cputime += getCPUTime(CPU) / N
		rss += uint64(Mem.PeakWorkingSetSize)
	}

	res.Metrics[prefix+"cputime"] = cputime
	res.Metrics[prefix+"rss"] = rss
	return out.String(), nil
}
Ejemplo n.º 6
0
func (d *dev) Close() (err error) {
	d.Drain()
	syscall.CloseHandle(d.ev.r)
	syscall.CloseHandle(d.ev.w)
	if e := syscall.CloseHandle(d.fd); e != nil {
		err = d.error("close", e)
	}
	return nil
}
Ejemplo n.º 7
0
// Login and load user profile. Also, set finalizer on s to logout() above.
func (s *LoginInfo) Prepare() error {
	var err error
	if s.Username == "" {
		return nil
	}

	ec := tools.ErrorContext("LoginInfo.Prepare")

	s.HUser, err = win32.LogonUser(
		syscall.StringToUTF16Ptr(s.Username),
		syscall.StringToUTF16Ptr("."),
		syscall.StringToUTF16Ptr(s.Password),
		win32.LOGON32_LOGON_INTERACTIVE,
		win32.LOGON32_PROVIDER_DEFAULT)

	if err != nil {
		return ec.NewError(err)
	}

	s.HProfile, err = loadProfile(s.HUser, s.Username)

	if err != nil {
		syscall.CloseHandle(s.HUser)
		s.HUser = syscall.InvalidHandle
		return ec.NewError(err)
	}

	runtime.SetFinalizer(s, logout)
	return nil
}
Ejemplo n.º 8
0
// TODO(pknap) : doc
func (r *readdcw) loop() {
	var n, key uint32
	var overlapped *syscall.Overlapped
	for {
		err := syscall.GetQueuedCompletionStatus(r.cph, &n, &key, &overlapped, syscall.INFINITE)
		if key == stateCPClose {
			r.Lock()
			handle := r.cph
			r.cph = syscall.InvalidHandle
			r.Unlock()
			syscall.CloseHandle(handle)
			r.wg.Done()
			return
		}
		if overlapped == nil {
			// TODO: check key == rewatch delete or 0(panic)
			continue
		}
		overEx := (*overlappedEx)(unsafe.Pointer(overlapped))
		if n == 0 {
			r.loopstate(overEx)
		} else {
			r.loopevent(n, overEx)
			if err = overEx.parent.readDirChanges(); err != nil {
				// TODO: error handling
			}
		}
	}
}
Ejemplo n.º 9
0
func TestCreateToolhelp32Snapshot(t *testing.T) {
	handle, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
	if err != nil {
		t.Fatal(err)
	}
	defer syscall.CloseHandle(syscall.Handle(handle))

	// Iterate over the snapshots until our PID is found.
	pid := uint32(syscall.Getpid())
	for {
		process, err := Process32Next(handle)
		if errors.Cause(err) == syscall.ERROR_NO_MORE_FILES {
			break
		}
		if err != nil {
			t.Fatal(err)
		}

		t.Logf("CreateToolhelp32Snapshot: ProcessEntry32=%v", process)

		if process.ProcessID == pid {
			assert.EqualValues(t, syscall.Getppid(), process.ParentProcessID)
			return
		}
	}

	assert.Fail(t, "Snapshot not found for PID=%v", pid)
}
Ejemplo n.º 10
0
// findExePath searches for process pid, and returns its executable path.
func findExePath(pid int) (string, error) {
	// Original code suggested different approach (see below).
	// Maybe it could be useful in the future.
	//
	// Find executable path from PID/handle on Windows:
	// https://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx

	p, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid))
	if err != nil {
		return "", err
	}
	defer syscall.CloseHandle(p)

	n := uint32(128)
	for {
		buf := make([]uint16, int(n))
		err = _QueryFullProcessImageName(p, 0, &buf[0], &n)
		switch err {
		case syscall.ERROR_INSUFFICIENT_BUFFER:
			// try bigger buffer
			n *= 2
			// but stop if it gets too big
			if n > 10000 {
				return "", err
			}
		case nil:
			return syscall.UTF16ToString(buf[:n]), nil
		default:
			return "", err
		}
	}
}
Ejemplo n.º 11
0
func (s *winSys) loadFileId() error {
	if s.path == "" {
		// already done
		return nil
	}
	s.Lock()
	defer s.Unlock()
	pathp, e := syscall.UTF16PtrFromString(s.path)
	if e != nil {
		return e
	}
	h, e := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
	if e != nil {
		return e
	}
	defer syscall.CloseHandle(h)
	var i syscall.ByHandleFileInformation
	e = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
	if e != nil {
		return e
	}
	s.path = ""
	s.vol = i.VolumeSerialNumber
	s.idxhi = i.FileIndexHigh
	s.idxlo = i.FileIndexLow
	return nil
}
Ejemplo n.º 12
0
func getIno(path string) (ino *inode, err error) {
	pathp, e := syscall.UTF16PtrFromString(path)
	if e != nil {
		return nil, e
	}
	h, e := syscall.CreateFile(pathp,
		syscall.FILE_LIST_DIRECTORY,
		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
		nil, syscall.OPEN_EXISTING,
		syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, 0)
	if e != nil {
		return nil, os.NewSyscallError("CreateFile", e)
	}
	var fi syscall.ByHandleFileInformation
	if e = syscall.GetFileInformationByHandle(h, &fi); e != nil {
		syscall.CloseHandle(h)
		return nil, os.NewSyscallError("GetFileInformationByHandle", e)
	}
	ino = &inode{
		handle: h,
		volume: fi.VolumeSerialNumber,
		index:  uint64(fi.FileIndexHigh)<<32 | uint64(fi.FileIndexLow),
	}
	return ino, nil
}
Ejemplo n.º 13
0
// munmap Windows implementation
// Based on: https://github.com/edsrzf/mmap-go
// Based on: https://github.com/boltdb/bolt/bolt_windows.go
func munmap(b []byte) (err error) {
	handleLock.Lock()
	defer handleLock.Unlock()

	addr := (uintptr)(unsafe.Pointer(&b[0]))
	if err := syscall.UnmapViewOfFile(addr); err != nil {
		return os.NewSyscallError("UnmapViewOfFile", err)
	}

	handle, ok := handleMap[addr]
	if !ok {
		// should be impossible; we would've seen the error above
		return errors.New("unknown base address")
	}
	delete(handleMap, addr)

	e := syscall.CloseHandle(syscall.Handle(handle))
	if e != nil {
		return os.NewSyscallError("CloseHandle", e)
	}

	file, ok := fileMap[addr]
	if !ok {
		// should be impossible; we would've seen the error above
		return errors.New("unknown base address")
	}
	delete(fileMap, addr)

	e = file.Close()
	if e != nil {
		return errors.New("close file" + e.Error())
	}
	return nil
}
Ejemplo n.º 14
0
func munmap(b []byte) (err error) {
	m := MMap(b)
	dh := m.header()

	addr := dh.Data
	length := uintptr(dh.Len)

	flush(addr, length)
	err = syscall.UnmapViewOfFile(addr)
	if err != nil {
		return err
	}

	handleLock.Lock()
	defer handleLock.Unlock()
	handle, ok := handleMap[addr]
	if !ok {
		// should be impossible; we would've errored above
		return errors.New("unknown base address")
	}
	delete(handleMap, addr)

	e := syscall.CloseHandle(syscall.Handle(handle))
	return os.NewSyscallError("CloseHandle", e)
}
Ejemplo n.º 15
0
func openDevice(ifPattern string) (*Interface, error) {
	createNewTAPDevice()
	handle, err := queryNetworkKey()
	if err != nil {
		Log(Error, "Failed to query Windows registry: %v", err)
		return nil, err
	}
	dev, err := queryAdapters(handle)
	if err != nil {
		Log(Error, "Failed to query network adapters: %v", err)
		return nil, err
	}
	if dev == nil {
		Log(Error, "All devices are in use")
		return nil, errors.New("No free TAP devices")
	}
	if dev.Name == "" {
		Log(Error, "Failed to query network adapters: %v", err)
		return nil, errors.New("Empty network adapter")
	}
	err = syscall.CloseHandle(handle)
	if err != nil {
		Log(Error, "Failed to close retrieved handle: %v", err)
	}

	return dev, nil
}
Ejemplo n.º 16
0
func mmapFile(f *os.File) mmapData {
	st, err := f.Stat()
	if err != nil {
		log.Fatal(err)
	}
	size := st.Size()
	if int64(int(size+4095)) != size+4095 {
		log.Fatalf("%s: too large for mmap", f.Name())
	}
	if size == 0 {
		return mmapData{f, nil, nil}
	}
	h, err := syscall.CreateFileMapping(syscall.Handle(f.Fd()), nil, syscall.PAGE_READONLY, uint32(size>>32), uint32(size), nil)
	if err != nil {
		log.Fatalf("CreateFileMapping %s: %v", f.Name(), err)
	}
	defer syscall.CloseHandle(syscall.Handle(h))

	addr, err := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, 0)
	if err != nil {
		log.Fatalf("MapViewOfFile %s: %v", f.Name(), err)
	}

	data := (*[1 << 30]byte)(unsafe.Pointer(addr))
	return mmapData{f, data[:size], data[:]}
}
Ejemplo n.º 17
0
// Must run within the I/O thread.
func (w *Watcher) startRead(watch *watch) error {
	if e := syscall.CancelIo(watch.ino.handle); e != nil {
		w.Error <- os.NewSyscallError("CancelIo", e)
		w.deleteWatch(watch)
	}
	mask := toWindowsFlags(watch.mask)
	for _, m := range watch.names {
		mask |= toWindowsFlags(m)
	}
	if mask == 0 {
		if e := syscall.CloseHandle(watch.ino.handle); e != nil {
			w.Error <- os.NewSyscallError("CloseHandle", e)
		}
		delete(w.watches[watch.ino.volume], watch.ino.index)
		return nil
	}
	e := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0],
		uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0)
	if e != nil {
		err := os.NewSyscallError("ReadDirectoryChanges", e)
		if e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 {
			// Watched directory was probably removed
			if w.sendEvent(watch.path, watch.mask&FS_DELETE_SELF) {
				if watch.mask&FS_ONESHOT != 0 {
					watch.mask = 0
				}
			}
			err = nil
		}
		w.deleteWatch(watch)
		w.startRead(watch)
		return err
	}
	return nil
}
Ejemplo n.º 18
0
func (self *ProcTime) Get(pid int) error {
	handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid))

	defer syscall.CloseHandle(handle)

	if err != nil {
		return fmt.Errorf("OpenProcess fails with %v", err)

	}
	var CPU syscall.Rusage
	if err := syscall.GetProcessTimes(handle, &CPU.CreationTime, &CPU.ExitTime, &CPU.KernelTime, &CPU.UserTime); err != nil {
		return fmt.Errorf("GetProcessTimes fails with %v", err)
	}

	// convert to millis
	self.StartTime = uint64(FiletimeToDuration(&CPU.CreationTime).Nanoseconds() / 1e6)

	self.User = uint64(FiletimeToDuration(&CPU.UserTime).Nanoseconds() / 1e6)

	self.Sys = uint64(FiletimeToDuration(&CPU.KernelTime).Nanoseconds() / 1e6)

	self.Total = self.User + self.Sys

	return nil
}
Ejemplo n.º 19
0
// AcceptPipe accepts the next incoming call and returns the new connection.
func (l *PipeListener) AcceptPipe() (*PipeConn, error) {
	if l == nil || l.addr == "" || l.closed {
		return nil, syscall.EINVAL
	}

	// the first time we call accept, the handle will have been created by the Listen
	// call. This is to prevent race conditions where the client thinks the server
	// isn't listening because it hasn't actually called create yet. After the first time, we'll
	// have to create a new handle each time
	handle := l.handle
	if handle == 0 {
		var err error
		handle, err = createPipe(string(l.addr), false)
		if err != nil {
			return nil, err
		}
	} else {
		l.handle = 0
	}

	overlapped, err := newOverlapped()
	if err != nil {
		return nil, err
	}
	defer syscall.CloseHandle(overlapped.HEvent)
	if err := connectNamedPipe(handle, overlapped); err != nil && err != error_pipe_connected {
		if err == error_io_incomplete || err == syscall.ERROR_IO_PENDING {
			_, err = waitForCompletion(handle, overlapped)
		}
		if err != nil {
			return nil, err
		}
	}
	return &PipeConn{handle: handle, addr: l.addr}, nil
}
Ejemplo n.º 20
0
func Open(filename string) (mf *memfile, err error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	fs, err := f.Stat()
	if err != nil {
		return nil, err
	}
	fsize := fs.Size()
	fmap, err := syscall.CreateFileMapping(syscall.Handle(f.Fd()), nil, syscall.PAGE_READONLY, 0, uint32(fsize), nil)
	if err != nil {
		return nil, err
	}
	defer syscall.CloseHandle(fmap)
	ptr, err := syscall.MapViewOfFile(fmap, syscall.FILE_MAP_READ, 0, 0, uintptr(fsize))
	if err != nil {
		return nil, err
	}
	defer func() {
		if recover() != nil {
			mf = nil
			err = errors.New("Failed option a file")
		}
	}()
	return &memfile{ptr, fsize, (*[1 << 30]byte)(unsafe.Pointer(ptr))[:fsize]}, nil
}
Ejemplo n.º 21
0
func (self *ProcMem) Get(pid int) error {
	handle, err := syscall.OpenProcess(PROCESS_ALL_ACCESS, false, uint32(pid))

	defer syscall.CloseHandle(handle)

	if err != nil {
		return fmt.Errorf("OpenProcess fails with %v", err)
	}

	var mem PROCESS_MEMORY_COUNTERS_EX
	mem.CB = uint32(unsafe.Sizeof(mem))

	r1, _, e1 := procGetProcessMemoryInfo.Call(
		uintptr(handle),
		uintptr(unsafe.Pointer(&mem)),
		uintptr(mem.CB),
	)
	if r1 == 0 {
		if e1 != nil {
			return error(e1)
		} else {
			return syscall.EINVAL
		}
	}

	self.Resident = uint64(mem.WorkingSetSize)
	self.Size = uint64(mem.PrivateUsage)
	// Size contains only to the Private Bytes
	// Virtual Bytes are the Working Set plus paged Private Bytes and standby list.
	return nil
}
Ejemplo n.º 22
0
// re-implementation of private function in https://github.com/golang/go/blob/master/src/syscall/syscall_windows.go#L945
func getProcessEntry(pid int) (pe *syscall.ProcessEntry32, err error) {
	snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
	if err != nil {
		return nil, err
	}
	defer syscall.CloseHandle(syscall.Handle(snapshot))

	var processEntry syscall.ProcessEntry32
	processEntry.Size = uint32(unsafe.Sizeof(processEntry))
	err = syscall.Process32First(snapshot, &processEntry)
	if err != nil {
		return nil, err
	}

	for {
		if processEntry.ProcessID == uint32(pid) {
			pe = &processEntry
			return
		}

		err = syscall.Process32Next(snapshot, &processEntry)
		if err != nil {
			return nil, err
		}
	}
}
Ejemplo n.º 23
0
func (file *file) close() error {
	if file == nil {
		return syscall.EINVAL
	}
	if file.isdir() && file.dirinfo.isempty {
		// "special" empty directories
		return nil
	}
	if file.fd == syscall.InvalidHandle {
		return syscall.EINVAL
	}
	var e error
	if file.isdir() {
		e = syscall.FindClose(syscall.Handle(file.fd))
	} else {
		e = syscall.CloseHandle(syscall.Handle(file.fd))
	}
	var err error
	if e != nil {
		err = &PathError{"close", file.name, e}
	}
	file.fd = syscall.InvalidHandle // so it can't be closed again

	// no need for a finalizer anymore
	runtime.SetFinalizer(file, nil)
	return err
}
Ejemplo n.º 24
0
func (p Process) threads() ([]*Thread, error) {
	var ret []*Thread

	snapshot, err := win32.CreateToolhelp32Snapshot(win32.TH32CS_SNAPTHREAD, p.Pid)
	if err != nil {
		return ret, err
	}
	defer syscall.CloseHandle(snapshot)

	var thEntry win32.ThreadEntry32
	thEntry.Size = uint32(unsafe.Sizeof(thEntry))

	if err = win32.Thread32First(snapshot, &thEntry); err != nil {
		return ret, err
	}

	for {
		t := &Thread{
			ThreadID:       thEntry.ThreadID,
			OwnerProcessID: thEntry.OwnerProcessID,
			BasePriority:   thEntry.BasePriority,
		}
		ret = append(ret, t)

		err = win32.Thread32Next(snapshot, &thEntry)
		if err != nil {
			if err == syscall.ERROR_NO_MORE_FILES {
				break
			}
			return ret, err
		}
	}

	return ret, nil
}
Ejemplo n.º 25
0
func getProcessEntry(pid int) (pe *processEntry32, err error) {
	snapshot, _, e1 := CreateToolhelp32Snapshot.Call(th32cs_snapprocess, uintptr(0))
	if snapshot == uintptr(syscall.InvalidHandle) {
		err = fmt.Errorf("CreateToolhelp32Snapshot: %v", e1)
		return
	}
	defer syscall.CloseHandle(syscall.Handle(snapshot))

	var processEntry processEntry32
	processEntry.dwSize = uint32(unsafe.Sizeof(processEntry))
	ok, _, e1 := Process32First.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
	if ok == 0 {
		err = fmt.Errorf("Process32First: %v", e1)
		return
	}

	for {
		if processEntry.th32ProcessID == uint32(pid) {
			pe = &processEntry
			return
		}

		ok, _, e1 = Process32Next.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
		if ok == 0 {
			err = fmt.Errorf("Process32Next: %v", e1)
			return
		}
	}
}
Ejemplo n.º 26
0
func (process *jobProcess) Wait() (int, error) {
	s, e := syscall.WaitForSingleObject(syscall.Handle(process.processHandle), syscall.INFINITE)
	switch s {
	case syscall.WAIT_OBJECT_0:
		break
	case syscall.WAIT_FAILED:
		return -1, os.NewSyscallError("WaitForSingleObject", e)
	default:
		return -1, errors.New("os: unexpected result from WaitForSingleObject")
	}

	var ec uint32
	e = syscall.GetExitCodeProcess(syscall.Handle(process.processHandle), &ec)
	if e != nil {
		return -1, os.NewSyscallError("GetExitCodeProcess", e)
	}

	var u syscall.Rusage
	e = syscall.GetProcessTimes(syscall.Handle(process.processHandle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime)
	if e != nil {
		return -1, os.NewSyscallError("GetProcessTimes", e)
	}

	// NOTE(brainman): It seems that sometimes process is not dead
	// when WaitForSingleObject returns. But we do not know any
	// other way to wait for it. Sleeping for a while seems to do
	// the trick sometimes. So we will sleep and smell the roses.
	defer time.Sleep(5 * time.Millisecond)
	defer syscall.CloseHandle(syscall.Handle(process.processHandle))

	return int(ec), nil
}
Ejemplo n.º 27
0
func enableCurrentThreadPrivilege(privilegeName string) error {
	ct, err := windows.GetCurrentThread()
	if err != nil {
		return err
	}
	var t syscall.Token
	err = windows.OpenThreadToken(ct, syscall.TOKEN_QUERY|windows.TOKEN_ADJUST_PRIVILEGES, false, &t)
	if err != nil {
		return err
	}
	defer syscall.CloseHandle(syscall.Handle(t))

	var tp windows.TOKEN_PRIVILEGES

	privStr, err := syscall.UTF16PtrFromString(privilegeName)
	if err != nil {
		return err
	}
	err = windows.LookupPrivilegeValue(nil, privStr, &tp.Privileges[0].Luid)
	if err != nil {
		return err
	}
	tp.PrivilegeCount = 1
	tp.Privileges[0].Attributes = windows.SE_PRIVILEGE_ENABLED
	return windows.AdjustTokenPrivileges(t, false, &tp, 0, nil, nil)
}
Ejemplo n.º 28
0
func (fs *fileStat) loadFileId() error {
	fs.Lock()
	defer fs.Unlock()
	if fs.path == "" {
		// already done
		return nil
	}
	pathp, err := syscall.UTF16PtrFromString(fs.path)
	if err != nil {
		return err
	}
	h, err := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
	if err != nil {
		return err
	}
	defer syscall.CloseHandle(h)
	var i syscall.ByHandleFileInformation
	err = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
	if err != nil {
		return err
	}
	fs.path = ""
	fs.vol = i.VolumeSerialNumber
	fs.idxhi = i.FileIndexHigh
	fs.idxlo = i.FileIndexLow
	return nil
}
Ejemplo n.º 29
0
func queryIOCounters(name string, freq time.Duration, qio QueryIO) {
	h, err := syscall.Open(name, syscall.O_RDONLY, 0)
	if err != nil {
		log.Fatal(err)
	}

	for {
		select {
		case <-time.After(freq):
			diskPerf, err := win32.IoctlDiskPerformance(h)

			if err != nil {
				log.Fatal(err)
			}

			ioc := &IOCounters{
				Name:       name,
				ReadCount:  diskPerf.ReadCount,
				WriteCount: diskPerf.WriteCount,
				ReadBytes:  sysmon.Size(diskPerf.BytesRead),
				WriteBytes: sysmon.Size(diskPerf.BytesWritten),
				ReadTime:   toDuration(diskPerf.ReadTime),
				WriteTime:  toDuration(diskPerf.WriteTime),
				IoTime:     toTime(diskPerf.QueryTime),
			}
			qio.IOCounterChan <- ioc
		case <-qio.quit:
			// we have received a signal to stop
			syscall.CloseHandle(h)
			return
		}
	}
}
Ejemplo n.º 30
0
// Must run within the I/O thread.
func (w *Watcher) addWatch(pathname string, flags uint64) error {
	dir, err := getDir(pathname)
	if err != nil {
		return err
	}
	if flags&sys_FS_ONLYDIR != 0 && pathname != dir {
		return nil
	}
	ino, err := getIno(dir)
	if err != nil {
		return err
	}
	w.mu.Lock()
	watchEntry := w.watches.get(ino)
	w.mu.Unlock()
	if watchEntry == nil {
		if _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != nil {
			syscall.CloseHandle(ino.handle)
			return os.NewSyscallError("CreateIoCompletionPort", e)
		}
		watchEntry = &watch{
			ino:   ino,
			path:  dir,
			names: make(map[string]uint64),
		}
		w.mu.Lock()
		w.watches.set(ino, watchEntry)
		w.mu.Unlock()
		flags |= provisional
	} else {
		syscall.CloseHandle(ino.handle)
	}
	if pathname == dir {
		watchEntry.mask |= flags
	} else {
		watchEntry.names[filepath.Base(pathname)] |= flags
	}
	if err = w.startRead(watchEntry); err != nil {
		return err
	}
	if pathname == dir {
		watchEntry.mask &= ^provisional
	} else {
		watchEntry.names[filepath.Base(pathname)] &= ^provisional
	}
	return nil
}