func (p *Process) getFromSnapProcess(pid int32) (int32, int32, string, error) { snap := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPPROCESS, uint32(pid)) if snap == 0 { return 0, 0, "", syscall.GetLastError() } defer w32.CloseHandle(snap) var pe32 w32.PROCESSENTRY32 pe32.DwSize = uint32(unsafe.Sizeof(pe32)) if w32.Process32First(snap, &pe32) == false { return 0, 0, "", syscall.GetLastError() } if pe32.Th32ProcessID == uint32(pid) { szexe := syscall.UTF16ToString(pe32.SzExeFile[:]) return int32(pe32.Th32ParentProcessID), int32(pe32.CntThreads), szexe, nil } for w32.Process32Next(snap, &pe32) { if pe32.Th32ProcessID == uint32(pid) { szexe := syscall.UTF16ToString(pe32.SzExeFile[:]) return int32(pe32.Th32ParentProcessID), int32(pe32.CntThreads), szexe, nil } } return 0, 0, "", errors.New("Couldn't find pid:" + string(pid)) }
func CheckProcess(Threshold int) { fmt.Printf("%v CheckProcess ... ", time.Now()) // 프로세스 스냅샷 핸들 생성하기 hProcessSnap, _, _ := CreateToolhelp32Snapshot.Call(uintptr(TH32CS_SNAPPROCESS), 0) if hProcessSnap < 0 { syscall.GetLastError() log.Fatal("fail to call CreateToolhelp32Snapshot") // Fatal 은 os.Exit(1) 호출함 //os.Exit(1) } defer CloseHandle.Call(hProcessSnap) // 프로세스 리스트 proclist := make([]PROCESSENTRY32, 0, 500) var pi PROCESSENTRY32 // 사용하기 전 프로세스 정보가 담길 구조체 크기 설정해야함 pi.dwSize = uint32(unsafe.Sizeof(pi)) // https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms686701(v=vs.85).aspx // 현재 실행중인 프로세스들 파악하기 위해선 첫번째 프로세스르 찾고 순차적으로 // 다음 프로세스를 찾아 가는 방식을 취한다. // 첫번째 프로세스 찾기 ret, _, _ := Process32First.Call(hProcessSnap, uintptr(unsafe.Pointer(&pi))) if ret <= 0 { syscall.GetLastError() log.Fatal("there is no process info") // Fatal 은 os.Exit(1) 호출함 //os.Exit(1) } proclist = append(proclist, pi) for { ret, _, _ = Process32Next.Call(hProcessSnap, uintptr(unsafe.Pointer(&pi))) if ret <= 0 { fmt.Printf("Finding Process Finished ... ") break } proclist = append(proclist, pi) } fmt.Println("process cnt = ", len(proclist)) WriteLog(proclist) // cntUsage 값은 더이상 사용할 수없다. // for i := range proclist { // // fmt.Printf("pid=%d\tusage=%d\n", proclist[i].th32ProcessID, proclist[i].cntUsage) // if uint32(Threshold) < proclist[i].cntUsage { // WriteLog(proclist) // break // } // } }
func processes() ([]Process, error) { handle, _, _ := procCreateToolhelp32Snapshot.Call( 0x00000002, 0) if handle < 0 { return nil, syscall.GetLastError() } defer procCloseHandle.Call(handle) var entry PROCESSENTRY32 entry.Size = uint32(unsafe.Sizeof(entry)) ret, _, _ := procProcess32First.Call(handle, uintptr(unsafe.Pointer(&entry))) if ret == 0 { return nil, fmt.Errorf("Error retrieving process info.") } results := make([]Process, 0, 50) for { results = append(results, newWindowsProcess(&entry)) ret, _, _ := procProcess32Next.Call(handle, uintptr(unsafe.Pointer(&entry))) if ret == 0 { break } } return results, nil }
func modules(pid int) ([]windowsModule, error) { handle, _, _ := procCreateToolhelp32Snapshot.Call( 0x00000008, // TH32CS_SNAPMODULE uintptr(uint32(pid))) if handle < 0 { return nil, syscall.GetLastError() } defer procCloseHandle.Call(handle) var entry MODULEENTRY32 entry.Size = uint32(unsafe.Sizeof(entry)) ret, _, _ := procModule32First.Call(handle, uintptr(unsafe.Pointer(&entry))) if ret == 0 { return nil, fmt.Errorf("Error retrieving module info") } results := make([]windowsModule, 0, 50) for { results = append(results, newWindowsModule(&entry)) ret, _, _ := procModule32Next.Call(handle, uintptr(unsafe.Pointer(&entry))) if ret == 0 { break } } return results, nil }
// Creates a low-level keyboard hook using the SetWindowsHookEx function: // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx // // Each intercepted key, which was included in the 'forwardedKeys' configuration // variable (see NewKeyboardCapture), will be pushed to the 'KeyPressed' channel field. // Returns an error in case the initialization of the hook failed. // Calls to this function will block until KeyboardCapture.Stop() was called or the // WM_QUIT message was sent to the current process. func (t *KeyboardCapture) SyncReceive() error { isValidKey := func(key w32.DWORD) bool { for _, e := range t.forwardedKeys { if e == int(key) { return true } } return false } t.KeyPressed = make(chan int) t.keyboardHook = w32.SetWindowsHookEx(w32.WH_KEYBOARD_LL, (w32.HOOKPROC)(func(code int, wparam w32.WPARAM, lparam w32.LPARAM) w32.LRESULT { if code >= 0 && wparam == w32.WM_KEYDOWN { kbdstruct := (*w32.KBDLLHOOKSTRUCT)(unsafe.Pointer(lparam)) if isValidKey(kbdstruct.VkCode) { select { case t.KeyPressed <- int(kbdstruct.VkCode): default: } } } return w32.CallNextHookEx(t.keyboardHook, code, wparam, lparam) }), 0, 0) if t.keyboardHook == 0 { return syscall.GetLastError() } var msg w32.MSG for w32.GetMessage(&msg, 0, 0, 0) != 0 { } w32.UnhookWindowsHookEx(t.keyboardHook) t.keyboardHook = 0 return nil }
func (d *winDevice) Write(data []byte) error { // first make sure we send the correct amount of data to the device outSize := int(d.info.OutputReportLength) buffer := make([]byte, outSize, outSize) copy(buffer, data) ol := new(syscall.Overlapped) if err := syscall.WriteFile(d.handle, buffer, nil, ol); err != nil { // IO Pending is ok we simply wait for it to finish a few lines below // all other errors should be reported. if err != syscall.ERROR_IO_PENDING { return err } } // now wait for the overlapped device access to finish. var written C.DWORD if C.GetOverlappedResult(d.h(), (*C.OVERLAPPED)((unsafe.Pointer)(ol)), &written, C.TRUE) == 0 { return syscall.GetLastError() } if int(written) != outSize { return errors.New("written bytes missmatch!") } return nil }
// Creates a hidden window, required for capturing the mouse interaction with the // notify icon. Windows will call the WndProc of this window, whenever something happens // on the notify icon (e.g. mouse click). func (t *_NotifyIcon) createCallbackWindow() (err error) { className := "KeyFwdWindowClass" err = registerWindowClass(className, t.iconCallback) if err != nil { return } classNamePtr, _ := syscall.UTF16PtrFromString(className) t.hwnd = w32.CreateWindowEx( uint(w32.WS_EX_LEFT|w32.WS_EX_LTRREADING|w32.WS_EX_WINDOWEDGE), classNamePtr, nil, uint(w32.WS_OVERLAPPED|w32.WS_MINIMIZEBOX|w32.WS_SYSMENU|w32.WS_CLIPSIBLINGS|w32.WS_CAPTION), w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, 10, 10, w32.HWND_DESKTOP, w32.HMENU(0), w32.GetModuleHandle(""), unsafe.Pointer(uintptr(0)), ) if t.hwnd == 0 { return syscall.GetLastError() } return nil }
// Call ShellExecute-API: edit,explore,open and so on. func ShellExecute(action string, path string, param string, directory string) error { actionP, actionErr := syscall.UTF16PtrFromString(action) if actionErr != nil { return actionErr } pathP, pathErr := syscall.UTF16PtrFromString(path) if pathErr != nil { return pathErr } paramP, paramErr := syscall.UTF16PtrFromString(param) if paramErr != nil { return paramErr } directoryP, directoryErr := syscall.UTF16PtrFromString(directory) if directoryErr != nil { return directoryErr } status, _, _ := shellExecute.Call( uintptr(0), uintptr(unsafe.Pointer(actionP)), uintptr(unsafe.Pointer(pathP)), uintptr(unsafe.Pointer(paramP)), uintptr(unsafe.Pointer(directoryP)), SW_SHOWNORMAL) if status <= 32 { if err := syscall.GetLastError(); err != nil { return err } else { return fmt.Errorf("Error(%d) in ShellExecuteW()", status) } } return nil }
func CloseServiceHandle(hSCObject HANDLE) error { ret, _, _ := procCloseServiceHandle.Call(uintptr(hSCObject)) if ret == 0 { return syscall.GetLastError() } return 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 }
// TODO: Get percpu func CPUTimes(percpu bool) ([]CPUTimesStat, error) { var ret []CPUTimesStat var lpIdleTime common.FILETIME var lpKernelTime common.FILETIME var lpUserTime common.FILETIME r, _, _ := common.ProcGetSystemTimes.Call( uintptr(unsafe.Pointer(&lpIdleTime)), uintptr(unsafe.Pointer(&lpKernelTime)), uintptr(unsafe.Pointer(&lpUserTime))) if r == 0 { return ret, syscall.GetLastError() } LOT := float64(0.0000001) HIT := (LOT * 4294967296.0) idle := ((HIT * float64(lpIdleTime.DwHighDateTime)) + (LOT * float64(lpIdleTime.DwLowDateTime))) user := ((HIT * float64(lpUserTime.DwHighDateTime)) + (LOT * float64(lpUserTime.DwLowDateTime))) kernel := ((HIT * float64(lpKernelTime.DwHighDateTime)) + (LOT * float64(lpKernelTime.DwLowDateTime))) system := (kernel - idle) ret = append(ret, CPUTimesStat{ Idle: float64(idle), User: float64(user), System: float64(system), Total: float64(idle) + float64(user) + float64(system), }) return ret, nil }
func (self *ProcList) Get() error { var enumSize int var pids [1024]C.DWORD // If the function succeeds, the return value is nonzero. ret, _, _ := procEnumProcesses.Call( uintptr(unsafe.Pointer(&pids[0])), uintptr(unsafe.Sizeof(pids)), uintptr(unsafe.Pointer(&enumSize)), ) if ret == 0 { return syscall.GetLastError() } results := []int{} pids_size := enumSize / int(unsafe.Sizeof(pids[0])) for _, pid := range pids[:pids_size] { results = append(results, int(pid)) } self.List = results return nil }
func (self *FileSystemUsage) Get(path string) error { /* Get free, available, total free bytes: fsutil volume diskfree C: */ var availableBytes C.ULARGE_INTEGER var totalBytes C.ULARGE_INTEGER var totalFreeBytes C.ULARGE_INTEGER pathChars := C.CString(path) defer C.free(unsafe.Pointer(pathChars)) succeeded := C.GetDiskFreeSpaceEx((*C.CHAR)(pathChars), &availableBytes, &totalBytes, &totalFreeBytes) if succeeded == C.FALSE { return syscall.GetLastError() } self.Total = *(*uint64)(unsafe.Pointer(&totalBytes)) self.Free = *(*uint64)(unsafe.Pointer(&totalFreeBytes)) self.Used = self.Total - self.Free self.Avail = *(*uint64)(unsafe.Pointer(&availableBytes)) return nil }
func GetTickCount64() uint64 { r, _, _ := procGetTickCount64.Call() if r == 0 { log.Fatal(syscall.GetLastError()) } return uint64(r) }
func shellNotifyIcon(message w32.DWORD, nid *_NOTIFYICONDATA) error { ret, _, _ := procShell_NotifyIcon.Call( uintptr(message), uintptr(unsafe.Pointer(nid)), ) if ret == w32.FALSE { return syscall.GetLastError() } return nil }
func newHandle(c *Config) (handle syscall.Handle, err error) { handle, err = syscall.CreateFile( syscall.StringToUTF16Ptr(c.Address), syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, // mode nil, // security syscall.OPEN_EXISTING, // create mode 0, // attributes 0) // templates if err != nil { return } defer func() { if err != nil { syscall.CloseHandle(handle) } }() var dcb C.DCB dcb.BaudRate = C.DWORD(c.BaudRate) // Data bits if c.DataBits == 0 { dcb.ByteSize = 8 } else { dcb.ByteSize = C.BYTE(c.DataBits) } // Stop bits switch c.StopBits { case 0, 1: // Default is one stop bit. dcb.StopBits = C.ONESTOPBIT case 2: dcb.StopBits = C.TWOSTOPBITS default: err = fmt.Errorf("serial: unsupported stop bits %v", c.StopBits) return } // Parity switch c.Parity { case "", "E": // Default parity mode is Even. dcb.Parity = C.EVENPARITY case "O": dcb.Parity = C.ODDPARITY case "N": dcb.Parity = C.NOPARITY default: err = fmt.Errorf("serial: unsupported parity %v", c.Parity) return } if C.SetCommState(C.HANDLE(handle), &dcb) == 0 { err = fmt.Errorf("serial: could not set device state: %v", syscall.GetLastError()) return } return }
func GetProcessIoCounters(h syscall.Handle) (*IOCounters, error) { var ioc IOCounters r, _, _ := procGetProcessIoCounters.Call(uintptr(h), uintptr(unsafe.Pointer(&ioc))) if r == 0 { return nil, syscall.GetLastError() } return &ioc, nil }
// CreateToolhelp32Snapshot takes a snapshot of the specified processes, as well // as the heaps, modules, and threads used by these processes. // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682489(v=vs.85).aspx func CreateToolhelp32Snapshot(flags, pid uint32) (syscall.Handle, error) { h, err := _CreateToolhelp32Snapshot(flags, pid) if err != nil { return syscall.InvalidHandle, err } if h == syscall.InvalidHandle { return syscall.InvalidHandle, syscall.GetLastError() } return h, nil }
func BootTime() (uint64, error) { var lpSystemTimeAsFileTime FILETIME r, _, _ := procGetSystemTimeAsFileTime.Call(uintptr(unsafe.Pointer(&lpSystemTimeAsFileTime))) if r == 0 { return 0, syscall.GetLastError() } // TODO: This calc is wrong. ll := (uint32(lpSystemTimeAsFileTime.DwHighDateTime))<<32 + lpSystemTimeAsFileTime.DwLowDateTime pt := (uint64(ll) - 116444736000000000) / 10000000 u, _, _ := procGetTickCount.Call() if u == 0 { return 0, syscall.GetLastError() } uptime := uint64(u) / 1000 return uint64(pt - uptime), nil }
// Get utf8(go-native) string // from ansi string (current codepage multibyte string) func AtoU(mbcs []byte) (string, error) { if mbcs == nil || len(mbcs) <= 0 { return "", nil } size, _, _ := multiByteToWideChar.Call(CP_THREAD_ACP, 0, uintptr(unsafe.Pointer(&mbcs[0])), uintptr(len(mbcs)), uintptr(0), 0) if size <= 0 { return "", syscall.GetLastError() } utf16 := make([]uint16, size) rc, _, _ := multiByteToWideChar.Call(CP_THREAD_ACP, 0, uintptr(unsafe.Pointer(&mbcs[0])), uintptr(len(mbcs)), uintptr(unsafe.Pointer(&utf16[0])), size) if rc == 0 { return "", syscall.GetLastError() } return syscall.UTF16ToString(utf16), nil }
func (d *winDevice) WriteFeature(data []byte) error { // ensure the correct amount of data buffer := make([]byte, d.info.FeatureReportLength, d.info.FeatureReportLength) copy(buffer, data) if C.HidD_SetFeature(d.h(), unsafe.Pointer(&buffer[0]), C.DWORD(len(buffer))) != 0 { return nil } else { return syscall.GetLastError() } }
func GetProcessHandleCount(h syscall.Handle) (uint32, error) { var count uint32 r, _, _ := procGetProcessHandleCount.Call(uintptr(h), uintptr(unsafe.Pointer(&count))) if r == 0 { return 0, syscall.GetLastError() } return count, nil }
// GetStats - return system statistics for windows. func GetStats() (stats Stats, err error) { var memInfo memoryStatusEx memInfo.cbSize = uint32(unsafe.Sizeof(memInfo)) mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))) if mem == 0 { return Stats{}, syscall.GetLastError() } stats = Stats{ TotalRAM: memInfo.ullTotalPhys, } return stats, nil }
func OpenService(hSCManager HANDLE, lpServiceName string, dwDesiredAccess DWORD) (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 (p *Process) Terminate() error { // PROCESS_TERMINATE = 0x0001 proc := w32.OpenProcess(0x0001, false, uint32(p.Pid)) ret := w32.TerminateProcess(proc, 0) w32.CloseHandle(proc) if ret == false { return syscall.GetLastError() } else { return nil } }
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 GetSystemTimes(IdleTime, KernelTime, UserTime *syscall.Filetime) error { r, _, _ := procGetSystemTimes.Call( uintptr(unsafe.Pointer(IdleTime)), uintptr(unsafe.Pointer(KernelTime)), uintptr(unsafe.Pointer(UserTime))) if r == 0 { return syscall.GetLastError() } return nil }
func GetPerformanceInfo() (*PerformanceInformation, error) { var pi PerformanceInformation r, _, _ := procGetPerformanceInfo.Call( uintptr(unsafe.Pointer(&pi)), uintptr(unsafe.Sizeof(pi))) if r == 0 { return nil, syscall.GetLastError() } return &pi, nil }
func GetProcessMemoryInfo(h syscall.Handle) (*ProcessMemoryCountersEx, error) { var pmc ProcessMemoryCountersEx r, _, _ := procGetProcessMemoryInfo.Call(uintptr(h), uintptr(unsafe.Pointer(&pmc)), uintptr(unsafe.Sizeof(pmc))) if r == 0 { return nil, syscall.GetLastError() } return &pmc, nil }
// Register a new window class for the current process. A window with the specified // class name will use the given WndProc callback function. func registerWindowClass(className string, callback _WindowProc) error { classNamePtr, _ := syscall.UTF16PtrFromString(className) var winClass w32.WNDCLASSEX winClass.Size = uint32(unsafe.Sizeof(winClass)) winClass.Instance = w32.GetModuleHandle("") winClass.ClassName = classNamePtr winClass.WndProc = syscall.NewCallback(callback) if w32.RegisterClassEx(&winClass) == 0 { return syscall.GetLastError() } return nil }