mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-05 08:37:31 -04:00
windows: add definitions and functions for ProcThreadAttributeList
The bulk of the documentation for these is in: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute This allows creating processes from scratch that use advanced options, such as changing the process parent. Fixes golang/go#44005. Change-Id: Id5cc5400541e57710b9e888cd37ef4f925d510fe Reviewed-on: https://go-review.googlesource.com/c/sys/+/288412 Trust: Jason A. Donenfeld <Jason@zx2c4.com> Trust: Alex Brainman <alex.brainman@gmail.com> Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
@@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
|
import (
|
||||||
|
errorspkg "errors"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
// EscapeArg rewrites command line argument s as prescribed
|
// EscapeArg rewrites command line argument s as prescribed
|
||||||
// in http://msdn.microsoft.com/en-us/library/ms880421.
|
// in http://msdn.microsoft.com/en-us/library/ms880421.
|
||||||
// This function returns "" (2 double quotes) if s is empty.
|
// This function returns "" (2 double quotes) if s is empty.
|
||||||
@@ -95,3 +100,31 @@ func FullPath(name string) (path string, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewProcThreadAttributeList allocates a new ProcThreadAttributeList, with the requested maximum number of attributes.
|
||||||
|
func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeList, error) {
|
||||||
|
var size uintptr
|
||||||
|
err := initializeProcThreadAttributeList(nil, maxAttrCount, 0, &size)
|
||||||
|
if err != ERROR_INSUFFICIENT_BUFFER {
|
||||||
|
if err == nil {
|
||||||
|
return nil, errorspkg.New("unable to query buffer size from InitializeProcThreadAttributeList")
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
al := (*ProcThreadAttributeList)(unsafe.Pointer(&make([]byte, size)[0]))
|
||||||
|
err = initializeProcThreadAttributeList(al, maxAttrCount, 0, &size)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return al, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update modifies the ProcThreadAttributeList using UpdateProcThreadAttribute.
|
||||||
|
func (al *ProcThreadAttributeList) Update(attribute uintptr, flags uint32, value unsafe.Pointer, size uintptr, prevValue uintptr, returnedSize *uintptr) error {
|
||||||
|
return updateProcThreadAttribute(al, flags, attribute, uintptr(value), size, prevValue, returnedSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete frees ProcThreadAttributeList's resources.
|
||||||
|
func (al *ProcThreadAttributeList) Delete() {
|
||||||
|
deleteProcThreadAttributeList(al)
|
||||||
|
}
|
||||||
|
|||||||
@@ -214,6 +214,9 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||||||
//sys CancelIo(s Handle) (err error)
|
//sys CancelIo(s Handle) (err error)
|
||||||
//sys CancelIoEx(s Handle, o *Overlapped) (err error)
|
//sys CancelIoEx(s Handle, o *Overlapped) (err error)
|
||||||
//sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW
|
//sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW
|
||||||
|
//sys initializeProcThreadAttributeList(attrlist *ProcThreadAttributeList, attrcount uint32, flags uint32, size *uintptr) (err error) = InitializeProcThreadAttributeList
|
||||||
|
//sys deleteProcThreadAttributeList(attrlist *ProcThreadAttributeList) = DeleteProcThreadAttributeList
|
||||||
|
//sys updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, attr uintptr, value uintptr, size uintptr, prevvalue uintptr, returnedsize *uintptr) (err error) = UpdateProcThreadAttribute
|
||||||
//sys OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error)
|
//sys OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error)
|
||||||
//sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW
|
//sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW
|
||||||
//sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId
|
//sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId
|
||||||
|
|||||||
@@ -215,6 +215,18 @@ const (
|
|||||||
INHERIT_PARENT_AFFINITY = 0x00010000
|
INHERIT_PARENT_AFFINITY = 0x00010000
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// attributes for ProcThreadAttributeList
|
||||||
|
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000
|
||||||
|
PROC_THREAD_ATTRIBUTE_HANDLE_LIST = 0x00020002
|
||||||
|
PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY = 0x00030003
|
||||||
|
PROC_THREAD_ATTRIBUTE_PREFERRED_NODE = 0x00020004
|
||||||
|
PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR = 0x00030005
|
||||||
|
PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = 0x00020007
|
||||||
|
PROC_THREAD_ATTRIBUTE_UMS_THREAD = 0x00030006
|
||||||
|
PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL = 0x0002000b
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// flags for CreateToolhelp32Snapshot
|
// flags for CreateToolhelp32Snapshot
|
||||||
TH32CS_SNAPHEAPLIST = 0x01
|
TH32CS_SNAPHEAPLIST = 0x01
|
||||||
@@ -886,6 +898,19 @@ type StartupInfo struct {
|
|||||||
StdErr Handle
|
StdErr Handle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StartupInfoEx struct {
|
||||||
|
StartupInfo
|
||||||
|
ProcThreadAttributeList *ProcThreadAttributeList
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcThreadAttributeList is a placeholder type to represent a PROC_THREAD_ATTRIBUTE_LIST.
|
||||||
|
//
|
||||||
|
// To create a *ProcThreadAttributeList, use NewProcThreadAttributeList, and
|
||||||
|
// free its memory using ProcThreadAttributeList.Delete.
|
||||||
|
type ProcThreadAttributeList struct {
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type ProcessInformation struct {
|
type ProcessInformation struct {
|
||||||
Process Handle
|
Process Handle
|
||||||
Thread Handle
|
Thread Handle
|
||||||
|
|||||||
@@ -188,6 +188,7 @@ var (
|
|||||||
procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot")
|
procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot")
|
||||||
procDefineDosDeviceW = modkernel32.NewProc("DefineDosDeviceW")
|
procDefineDosDeviceW = modkernel32.NewProc("DefineDosDeviceW")
|
||||||
procDeleteFileW = modkernel32.NewProc("DeleteFileW")
|
procDeleteFileW = modkernel32.NewProc("DeleteFileW")
|
||||||
|
procDeleteProcThreadAttributeList = modkernel32.NewProc("DeleteProcThreadAttributeList")
|
||||||
procDeleteVolumeMountPointW = modkernel32.NewProc("DeleteVolumeMountPointW")
|
procDeleteVolumeMountPointW = modkernel32.NewProc("DeleteVolumeMountPointW")
|
||||||
procDeviceIoControl = modkernel32.NewProc("DeviceIoControl")
|
procDeviceIoControl = modkernel32.NewProc("DeviceIoControl")
|
||||||
procDuplicateHandle = modkernel32.NewProc("DuplicateHandle")
|
procDuplicateHandle = modkernel32.NewProc("DuplicateHandle")
|
||||||
@@ -266,6 +267,7 @@ var (
|
|||||||
procGetVolumePathNameW = modkernel32.NewProc("GetVolumePathNameW")
|
procGetVolumePathNameW = modkernel32.NewProc("GetVolumePathNameW")
|
||||||
procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW")
|
procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW")
|
||||||
procGetWindowsDirectoryW = modkernel32.NewProc("GetWindowsDirectoryW")
|
procGetWindowsDirectoryW = modkernel32.NewProc("GetWindowsDirectoryW")
|
||||||
|
procInitializeProcThreadAttributeList = modkernel32.NewProc("InitializeProcThreadAttributeList")
|
||||||
procIsWow64Process = modkernel32.NewProc("IsWow64Process")
|
procIsWow64Process = modkernel32.NewProc("IsWow64Process")
|
||||||
procIsWow64Process2 = modkernel32.NewProc("IsWow64Process2")
|
procIsWow64Process2 = modkernel32.NewProc("IsWow64Process2")
|
||||||
procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW")
|
procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW")
|
||||||
@@ -324,6 +326,7 @@ var (
|
|||||||
procThread32Next = modkernel32.NewProc("Thread32Next")
|
procThread32Next = modkernel32.NewProc("Thread32Next")
|
||||||
procUnlockFileEx = modkernel32.NewProc("UnlockFileEx")
|
procUnlockFileEx = modkernel32.NewProc("UnlockFileEx")
|
||||||
procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile")
|
procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile")
|
||||||
|
procUpdateProcThreadAttribute = modkernel32.NewProc("UpdateProcThreadAttribute")
|
||||||
procVirtualAlloc = modkernel32.NewProc("VirtualAlloc")
|
procVirtualAlloc = modkernel32.NewProc("VirtualAlloc")
|
||||||
procVirtualFree = modkernel32.NewProc("VirtualFree")
|
procVirtualFree = modkernel32.NewProc("VirtualFree")
|
||||||
procVirtualLock = modkernel32.NewProc("VirtualLock")
|
procVirtualLock = modkernel32.NewProc("VirtualLock")
|
||||||
@@ -1574,6 +1577,11 @@ func DeleteFile(path *uint16) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deleteProcThreadAttributeList(attrlist *ProcThreadAttributeList) {
|
||||||
|
syscall.Syscall(procDeleteProcThreadAttributeList.Addr(), 1, uintptr(unsafe.Pointer(attrlist)), 0, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) {
|
func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procDeleteVolumeMountPointW.Addr(), 1, uintptr(unsafe.Pointer(volumeMountPoint)), 0, 0)
|
r1, _, e1 := syscall.Syscall(procDeleteVolumeMountPointW.Addr(), 1, uintptr(unsafe.Pointer(volumeMountPoint)), 0, 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -2235,6 +2243,14 @@ func getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initializeProcThreadAttributeList(attrlist *ProcThreadAttributeList, attrcount uint32, flags uint32, size *uintptr) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall6(procInitializeProcThreadAttributeList.Addr(), 4, uintptr(unsafe.Pointer(attrlist)), uintptr(attrcount), uintptr(flags), uintptr(unsafe.Pointer(size)), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func IsWow64Process(handle Handle, isWow64 *bool) (err error) {
|
func IsWow64Process(handle Handle, isWow64 *bool) (err error) {
|
||||||
var _p0 uint32
|
var _p0 uint32
|
||||||
if *isWow64 {
|
if *isWow64 {
|
||||||
@@ -2776,6 +2792,14 @@ func UnmapViewOfFile(addr uintptr) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, attr uintptr, value uintptr, size uintptr, prevvalue uintptr, returnedsize *uintptr) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall9(procUpdateProcThreadAttribute.Addr(), 7, uintptr(unsafe.Pointer(attrlist)), uintptr(flags), uintptr(attr), uintptr(value), uintptr(size), uintptr(prevvalue), uintptr(unsafe.Pointer(returnedsize)), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) {
|
func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) {
|
||||||
r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0)
|
r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0)
|
||||||
value = uintptr(r0)
|
value = uintptr(r0)
|
||||||
|
|||||||
Reference in New Issue
Block a user