Skip to content

Commit f36f782

Browse files
committed
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 <[email protected]> Trust: Alex Brainman <[email protected]> Run-TryBot: Jason A. Donenfeld <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Alex Brainman <[email protected]>
1 parent a50acf3 commit f36f782

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

windows/exec_windows.go

+33
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
package windows
88

9+
import (
10+
errorspkg "errors"
11+
"unsafe"
12+
)
13+
914
// EscapeArg rewrites command line argument s as prescribed
1015
// in http://msdn.microsoft.com/en-us/library/ms880421.
1116
// This function returns "" (2 double quotes) if s is empty.
@@ -95,3 +100,31 @@ func FullPath(name string) (path string, err error) {
95100
}
96101
}
97102
}
103+
104+
// NewProcThreadAttributeList allocates a new ProcThreadAttributeList, with the requested maximum number of attributes.
105+
func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeList, error) {
106+
var size uintptr
107+
err := initializeProcThreadAttributeList(nil, maxAttrCount, 0, &size)
108+
if err != ERROR_INSUFFICIENT_BUFFER {
109+
if err == nil {
110+
return nil, errorspkg.New("unable to query buffer size from InitializeProcThreadAttributeList")
111+
}
112+
return nil, err
113+
}
114+
al := (*ProcThreadAttributeList)(unsafe.Pointer(&make([]byte, size)[0]))
115+
err = initializeProcThreadAttributeList(al, maxAttrCount, 0, &size)
116+
if err != nil {
117+
return nil, err
118+
}
119+
return al, err
120+
}
121+
122+
// Update modifies the ProcThreadAttributeList using UpdateProcThreadAttribute.
123+
func (al *ProcThreadAttributeList) Update(attribute uintptr, flags uint32, value unsafe.Pointer, size uintptr, prevValue uintptr, returnedSize *uintptr) error {
124+
return updateProcThreadAttribute(al, flags, attribute, uintptr(value), size, prevValue, returnedSize)
125+
}
126+
127+
// Delete frees ProcThreadAttributeList's resources.
128+
func (al *ProcThreadAttributeList) Delete() {
129+
deleteProcThreadAttributeList(al)
130+
}

windows/syscall_windows.go

+3
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ func NewCallbackCDecl(fn interface{}) uintptr {
214214
//sys CancelIo(s Handle) (err error)
215215
//sys CancelIoEx(s Handle, o *Overlapped) (err error)
216216
//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
217+
//sys initializeProcThreadAttributeList(attrlist *ProcThreadAttributeList, attrcount uint32, flags uint32, size *uintptr) (err error) = InitializeProcThreadAttributeList
218+
//sys deleteProcThreadAttributeList(attrlist *ProcThreadAttributeList) = DeleteProcThreadAttributeList
219+
//sys updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, attr uintptr, value uintptr, size uintptr, prevvalue uintptr, returnedsize *uintptr) (err error) = UpdateProcThreadAttribute
217220
//sys OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error)
218221
//sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW
219222
//sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId

windows/types_windows.go

+25
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,18 @@ const (
215215
INHERIT_PARENT_AFFINITY = 0x00010000
216216
)
217217

218+
const (
219+
// attributes for ProcThreadAttributeList
220+
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000
221+
PROC_THREAD_ATTRIBUTE_HANDLE_LIST = 0x00020002
222+
PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY = 0x00030003
223+
PROC_THREAD_ATTRIBUTE_PREFERRED_NODE = 0x00020004
224+
PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR = 0x00030005
225+
PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = 0x00020007
226+
PROC_THREAD_ATTRIBUTE_UMS_THREAD = 0x00030006
227+
PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL = 0x0002000b
228+
)
229+
218230
const (
219231
// flags for CreateToolhelp32Snapshot
220232
TH32CS_SNAPHEAPLIST = 0x01
@@ -886,6 +898,19 @@ type StartupInfo struct {
886898
StdErr Handle
887899
}
888900

901+
type StartupInfoEx struct {
902+
StartupInfo
903+
ProcThreadAttributeList *ProcThreadAttributeList
904+
}
905+
906+
// ProcThreadAttributeList is a placeholder type to represent a PROC_THREAD_ATTRIBUTE_LIST.
907+
//
908+
// To create a *ProcThreadAttributeList, use NewProcThreadAttributeList, and
909+
// free its memory using ProcThreadAttributeList.Delete.
910+
type ProcThreadAttributeList struct {
911+
_ [1]byte
912+
}
913+
889914
type ProcessInformation struct {
890915
Process Handle
891916
Thread Handle

windows/zsyscall_windows.go

+24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)