commit 3a859d6dc39dc1907369f7c79c762f9205c31dd8 Author: 兔子 Date: Mon Mar 11 14:56:06 2019 +0800 init diff --git a/permission.go b/permission.go new file mode 100644 index 0000000..d7781ee --- /dev/null +++ b/permission.go @@ -0,0 +1,261 @@ +package wincmd + +import ( + "fmt" + "strconv" + "strings" + "unsafe" + + "b612.me/win32api" + "golang.org/x/sys/windows" + "golang.org/x/sys/windows/registry" +) + +func StartProcessWithSYS(appPath, cmdLine, workDir string, runas bool) error { + var ( + sessionId win32api.HANDLE + userToken win32api.TOKEN = 0 + envInfo win32api.HANDLE + impersonationToken win32api.HANDLE = 0 + startupInfo win32api.StartupInfo + processInfo win32api.ProcessInformation + sessionInformation win32api.HANDLE = win32api.HANDLE(0) + sessionCount int = 0 + sessionList []*win32api.WTS_SESSION_INFO = make([]*win32api.WTS_SESSION_INFO, 0) + err error + ) + if err := win32api.WTSEnumerateSessions(0, 0, 1, &sessionInformation, &sessionCount); err != nil { + return err + } + structSize := unsafe.Sizeof(win32api.WTS_SESSION_INFO{}) + current := uintptr(sessionInformation) + for i := 0; i < sessionCount; i++ { + sessionList = append(sessionList, (*win32api.WTS_SESSION_INFO)(unsafe.Pointer(current))) + current += structSize + } + if sessionId, err = func() (win32api.HANDLE, error) { + for i := range sessionList { + if sessionList[i].State == win32api.WTSActive { + return sessionList[i].SessionID, nil + } + } + if sessionId, err := win32api.WTSGetActiveConsoleSessionId(); sessionId == 0xFFFFFFFF { + return 0xFFFFFFFF, fmt.Errorf("get current user session token: call native WTSGetActiveConsoleSessionId: %s", err) + } else { + return win32api.HANDLE(sessionId), nil + } + }(); err != nil { + return err + } + + if err := win32api.WTSQueryUserToken(sessionId, &impersonationToken); err != nil { + return err + } + + if err := win32api.DuplicateTokenEx(impersonationToken, 0, 0, int(win32api.SecurityImpersonation), win32api.TokenPrimary, &userToken); err != nil { + return fmt.Errorf("call native DuplicateTokenEx: %s", err) + } + if runas { + var admin win32api.TOKEN_LINKED_TOKEN + var dt uintptr = 0 + if err := win32api.GetTokenInformation(impersonationToken, 19, uintptr(unsafe.Pointer(&admin)), uintptr(unsafe.Sizeof(admin)), &dt); err == nil { + userToken = admin.LinkedToken + } + } + if err := win32api.CloseHandle(impersonationToken); err != nil { + return fmt.Errorf("close windows handle used for token duplication: %s", err) + } + + if err := win32api.CreateEnvironmentBlock(&envInfo, userToken, 0); err != nil { + return fmt.Errorf("create environment details for process: %s", err) + } + creationFlags := win32api.CREATE_UNICODE_ENVIRONMENT | win32api.CREATE_NEW_CONSOLE + startupInfo.ShowWindow = win32api.SW_SHOW + startupInfo.Desktop = windows.StringToUTF16Ptr("winsta0\\default") + if err := win32api.CreateProcessAsUser(userToken, appPath, cmdLine, 0, 0, 0, + creationFlags, envInfo, workDir, &startupInfo, &processInfo); err != nil { + return fmt.Errorf("create process as user: %s", err) + } + return nil +} + +func GetRunningProcess() ([]map[string]string, error) { + result := []map[string]string{} + pHandle, err := win32api.CreateToolhelp32Snapshot(0x2, 0x0) + if err != nil { + return result, err + } + for { + var proc win32api.PROCESSENTRY32 + proc.DwSize = win32api.Ulong(unsafe.Sizeof(proc)) + if err := win32api.Process32Next(pHandle, &proc); err == nil { + bytetmp := proc.SzExeFile[0:] + var sakura []byte + for _, v := range bytetmp { + if v == byte(0) { + break + } + sakura = append(sakura, v) + } + result = append(result, map[string]string{"name": string(sakura), "pid": strconv.Itoa(int(proc.Th32ProcessID))}) + } else { + break + } + } + win32api.CloseHandle(pHandle) + return result, nil +} + +func IsProcessRunningByPID(pid int) bool { + pHandle, err := win32api.CreateToolhelp32Snapshot(0x2, 0x0) + if err != nil { + return false + } + for { + var proc win32api.PROCESSENTRY32 + proc.DwSize = win32api.Ulong(unsafe.Sizeof(proc)) + if err := win32api.Process32Next(pHandle, &proc); err == nil { + bytetmp := int(proc.Th32ProcessID) + if bytetmp == pid { + return true + } + } else { + break + } + } + win32api.CloseHandle(pHandle) + return false +} +func IsProcessRunning(name string) bool { + pHandle, err := win32api.CreateToolhelp32Snapshot(0x2, 0x0) + if err != nil { + return false + } + for { + var proc win32api.PROCESSENTRY32 + proc.DwSize = win32api.Ulong(unsafe.Sizeof(proc)) + if err := win32api.Process32Next(pHandle, &proc); err == nil { + bytetmp := proc.SzExeFile[0:] + var sakura []byte + for _, v := range bytetmp { + if v == byte(0) { + break + } + sakura = append(sakura, v) + } + if strings.ToLower(strings.TrimSpace(string(sakura))) == strings.ToLower(strings.TrimSpace(name)) { + return true + } + } else { + break + } + } + win32api.CloseHandle(pHandle) + return false +} + +func GetProcessCount(name string) int { + var res int = 0 + pHandle, err := win32api.CreateToolhelp32Snapshot(0x2, 0x0) + if err != nil { + return 0 + } + for { + var proc win32api.PROCESSENTRY32 + proc.DwSize = win32api.Ulong(unsafe.Sizeof(proc)) + if err := win32api.Process32Next(pHandle, &proc); err == nil { + bytetmp := proc.SzExeFile[0:] + var sakura []byte + for _, v := range bytetmp { + if v == byte(0) { + break + } + sakura = append(sakura, v) + } + if strings.ToLower(strings.TrimSpace(string(sakura))) == strings.ToLower(strings.TrimSpace(name)) { + res++ + } + } else { + break + } + } + win32api.CloseHandle(pHandle) + return res +} + +func Isas() bool { + _, errs := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM`, registry.ALL_ACCESS) + if errs != nil { + return false + } + return true +} + +func StartProcess(appPath, cmdLine, wordDir string, runas bool, ShowWindow int) bool { + var cst string + if runas { + cst = "runas" + } else { + cst = "open" + } + r := win32api.ShellExecute(0, cst, appPath, cmdLine, wordDir, ShowWindow) + if r != nil { + return false + } + return true +} +func StartProcessWithPID(appPath, cmdLine, workDir string, runas bool, ShowWindow int) int { + var sakura win32api.SHELLEXECUTEINFOW + sakura.Hwnd = 0 + sakura.NShow = ShowWindow + sakura.FMask = 0x00000040 + sakura.LpFile = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(appPath))) + sakura.LpDirectory = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(workDir))) + if runas { + sakura.LpVerb = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr("runas"))) + } else { + sakura.LpVerb = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr("open"))) + } + sakura.CbSize = win32api.DWORD(unsafe.Sizeof(sakura)) + + if err := win32api.ShellExecuteEx(&sakura); err != nil { + return 0 + } + return int(win32api.GetProcessId(sakura.HProcess)) +} + +func AutoRun(key, path string) (bool, error) { + reg, errs := registry.OpenKey(registry.LOCAL_MACHINE, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.ALL_ACCESS) + if errs != nil { + return false, errs + } + if errs = reg.SetStringValue(key, path); errs != nil { + return false, errs + } + return true, nil +} + +func DeleteAutoRun(key string) (bool, error) { + reg, errs := registry.OpenKey(registry.LOCAL_MACHINE, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.ALL_ACCESS) + if errs != nil { + return false, errs + } + if _, i, _ := reg.GetStringValue(key); i == 0 { + return true, nil + } + if errs = reg.DeleteValue(key); errs != nil { + return false, errs + } + return true, nil +} + +func IsAutoRun(key, path string) bool { + reg, errs := registry.OpenKey(registry.LOCAL_MACHINE, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.ALL_ACCESS) + if errs != nil { + return false + } + if sa, _, _ := reg.GetStringValue(key); sa == path { + return true + } + return false +}