- 修正 WTS 会话相关类型、枚举与活动会话选择逻辑 - 对齐 FILE_ID_DESCRIPTOR 布局与 FILE_ID_TYPE 语义,修复 OpenFileById 调用前提 - 修正 user32/shell32/kernel32 部分 API 的返回值、参数个数与错误处理 - 完善剪贴板更新格式读取的缓冲区重试逻辑 - 补充常用进程、线程、调试、桌面与会话 helper - 增加结构体布局、会话查询、剪贴板、CreateProcess 等回归测试 - 将默认 CreateProcess 相关测试切到 helper 进程,并保留显式开启的 cmd.exe 集成覆盖
129 lines
2.8 KiB
Go
129 lines
2.8 KiB
Go
package win32api
|
|
|
|
import (
|
|
"bytes"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
func (entry PROCESSENTRY32) ExeFile() string {
|
|
n := bytes.IndexByte(entry.SzExeFile[:], 0)
|
|
if n < 0 {
|
|
n = len(entry.SzExeFile)
|
|
}
|
|
return string(entry.SzExeFile[:n])
|
|
}
|
|
|
|
func (entry MODULEENTRY32W) ModuleName() string {
|
|
return syscall.UTF16ToString(entry.SzModule[:])
|
|
}
|
|
|
|
func (entry MODULEENTRY32W) ExePath() string {
|
|
return syscall.UTF16ToString(entry.SzExePath[:])
|
|
}
|
|
|
|
func (info DebugEventInfo) String() string {
|
|
return info.CodeName
|
|
}
|
|
|
|
func EnumerateProcesses() ([]PROCESSENTRY32, error) {
|
|
snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() {
|
|
_ = CloseHandle(snapshot)
|
|
}()
|
|
|
|
var entry PROCESSENTRY32
|
|
entry.DwSize = Ulong(unsafe.Sizeof(entry))
|
|
if err := Process32First(snapshot, &entry); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
processes := make([]PROCESSENTRY32, 0, 64)
|
|
for {
|
|
processes = append(processes, entry)
|
|
entry.DwSize = Ulong(unsafe.Sizeof(entry))
|
|
err = Process32Next(snapshot, &entry)
|
|
if err != nil {
|
|
if errno, ok := err.(syscall.Errno); ok && errno == ERROR_NO_MORE_FILES {
|
|
break
|
|
}
|
|
if err == syscall.EINVAL {
|
|
break
|
|
}
|
|
return nil, err
|
|
}
|
|
}
|
|
return processes, nil
|
|
}
|
|
|
|
func EnumerateThreads(ownerProcessID DWORD) ([]THREADENTRY32, error) {
|
|
snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() {
|
|
_ = CloseHandle(snapshot)
|
|
}()
|
|
|
|
var entry THREADENTRY32
|
|
entry.DwSize = DWORD(unsafe.Sizeof(entry))
|
|
if err := Thread32First(snapshot, &entry); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
threads := make([]THREADENTRY32, 0, 64)
|
|
for {
|
|
if ownerProcessID == 0 || entry.Th32OwnerProcessID == ownerProcessID {
|
|
threads = append(threads, entry)
|
|
}
|
|
entry.DwSize = DWORD(unsafe.Sizeof(entry))
|
|
err = Thread32Next(snapshot, &entry)
|
|
if err != nil {
|
|
if errno, ok := err.(syscall.Errno); ok && errno == ERROR_NO_MORE_FILES {
|
|
break
|
|
}
|
|
if err == syscall.EINVAL {
|
|
break
|
|
}
|
|
return nil, err
|
|
}
|
|
}
|
|
return threads, nil
|
|
}
|
|
|
|
func EnumerateModules(processID DWORD) ([]MODULEENTRY32W, error) {
|
|
snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE|TH32CS_SNAPMODULE32, processID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() {
|
|
_ = CloseHandle(snapshot)
|
|
}()
|
|
|
|
var entry MODULEENTRY32W
|
|
entry.DwSize = DWORD(unsafe.Sizeof(entry))
|
|
if err := Module32First(snapshot, &entry); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
modules := make([]MODULEENTRY32W, 0, 32)
|
|
for {
|
|
modules = append(modules, entry)
|
|
entry.DwSize = DWORD(unsafe.Sizeof(entry))
|
|
err = Module32Next(snapshot, &entry)
|
|
if err != nil {
|
|
if errno, ok := err.(syscall.Errno); ok && errno == ERROR_NO_MORE_FILES {
|
|
break
|
|
}
|
|
if err == syscall.EINVAL {
|
|
break
|
|
}
|
|
return nil, err
|
|
}
|
|
}
|
|
return modules, nil
|
|
}
|