]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: add support for proc thread attribute lists
authorJason A. Donenfeld <Jason@zx2c4.com>
Sun, 31 Jan 2021 16:37:20 +0000 (17:37 +0100)
committerJason A. Donenfeld <Jason@zx2c4.com>
Fri, 26 Feb 2021 18:23:16 +0000 (18:23 +0000)
This will allow us to pass additional attributes when starting
processes.

Updates #44011.

Change-Id: I4af365c5544a6d421830f247593ec970200e5e03
Reviewed-on: https://go-review.googlesource.com/c/go/+/288296
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Trust: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
src/syscall/syscall_windows.go
src/syscall/types_windows.go
src/syscall/zsyscall_windows.go

index ee5311b176b7d0d52a0f57bbd16d238c84889b65..cc8dc487d354b74c99d97e1c912cfbe025669772 100644 (file)
@@ -284,6 +284,9 @@ func NewCallbackCDecl(fn interface{}) uintptr {
 // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
 //sys  CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW
 //sys  CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW
+//sys  initializeProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, attrcount uint32, flags uint32, size *uintptr) (err error) = InitializeProcThreadAttributeList
+//sys  deleteProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST) = DeleteProcThreadAttributeList
+//sys  updateProcThreadAttribute(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, flags uint32, attr uintptr, value uintptr, size uintptr, prevvalue uintptr, returnedsize *uintptr) (err error) = UpdateProcThreadAttribute
 
 // syscall interface implementation for other packages
 
@@ -1240,3 +1243,23 @@ func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overla
 func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) error {
        return postQueuedCompletionStatus(cphandle, qty, uintptr(key), overlapped)
 }
+
+// newProcThreadAttributeList allocates new PROC_THREAD_ATTRIBUTE_LIST, with
+// the requested maximum number of attributes, which must be cleaned up by
+// deleteProcThreadAttributeList.
+func newProcThreadAttributeList(maxAttrCount uint32) (*_PROC_THREAD_ATTRIBUTE_LIST, 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 := (*_PROC_THREAD_ATTRIBUTE_LIST)(unsafe.Pointer(&make([]byte, size)[0]))
+       err = initializeProcThreadAttributeList(al, maxAttrCount, 0, &size)
+       if err != nil {
+               return nil, err
+       }
+       return al, nil
+}
index 5fef5c94774c8910a18d656a5602871b1d1dfe21..384b5b4f2c1f6ce12361d0c9aa5fb7bf685222cb 100644 (file)
@@ -490,6 +490,22 @@ type StartupInfo struct {
        StdErr        Handle
 }
 
+type _PROC_THREAD_ATTRIBUTE_LIST struct {
+       _ [1]byte
+}
+
+const (
+       _PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000
+       _PROC_THREAD_ATTRIBUTE_HANDLE_LIST    = 0x00020002
+)
+
+type _STARTUPINFOEXW struct {
+       StartupInfo
+       ProcThreadAttributeList *_PROC_THREAD_ATTRIBUTE_LIST
+}
+
+const _EXTENDED_STARTUPINFO_PRESENT = 0x00080000
+
 type ProcessInformation struct {
        Process   Handle
        Thread    Handle
index b1480ba7df68ea42a17890f0d7ba7f4f3185fd16..b08e6ac5c2a8b99be30f4fdfcefd2f13f28d12e2 100644 (file)
@@ -93,6 +93,7 @@ var (
        procCreateSymbolicLinkW                = modkernel32.NewProc("CreateSymbolicLinkW")
        procCreateToolhelp32Snapshot           = modkernel32.NewProc("CreateToolhelp32Snapshot")
        procDeleteFileW                        = modkernel32.NewProc("DeleteFileW")
+       procDeleteProcThreadAttributeList      = modkernel32.NewProc("DeleteProcThreadAttributeList")
        procDeviceIoControl                    = modkernel32.NewProc("DeviceIoControl")
        procDuplicateHandle                    = modkernel32.NewProc("DuplicateHandle")
        procExitProcess                        = modkernel32.NewProc("ExitProcess")
@@ -131,6 +132,7 @@ var (
        procGetTempPathW                       = modkernel32.NewProc("GetTempPathW")
        procGetTimeZoneInformation             = modkernel32.NewProc("GetTimeZoneInformation")
        procGetVersion                         = modkernel32.NewProc("GetVersion")
+       procInitializeProcThreadAttributeList  = modkernel32.NewProc("InitializeProcThreadAttributeList")
        procLoadLibraryW                       = modkernel32.NewProc("LoadLibraryW")
        procLocalFree                          = modkernel32.NewProc("LocalFree")
        procMapViewOfFile                      = modkernel32.NewProc("MapViewOfFile")
@@ -153,6 +155,7 @@ var (
        procSetHandleInformation               = modkernel32.NewProc("SetHandleInformation")
        procTerminateProcess                   = modkernel32.NewProc("TerminateProcess")
        procUnmapViewOfFile                    = modkernel32.NewProc("UnmapViewOfFile")
+       procUpdateProcThreadAttribute          = modkernel32.NewProc("UpdateProcThreadAttribute")
        procVirtualLock                        = modkernel32.NewProc("VirtualLock")
        procVirtualUnlock                      = modkernel32.NewProc("VirtualUnlock")
        procWaitForSingleObject                = modkernel32.NewProc("WaitForSingleObject")
@@ -569,6 +572,11 @@ func DeleteFile(path *uint16) (err error) {
        return
 }
 
+func deleteProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST) {
+       Syscall(procDeleteProcThreadAttributeList.Addr(), 1, uintptr(unsafe.Pointer(attrlist)), 0, 0)
+       return
+}
+
 func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) {
        r1, _, e1 := Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0)
        if r1 == 0 {
@@ -897,6 +905,14 @@ func GetVersion() (ver uint32, err error) {
        return
 }
 
+func initializeProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, attrcount uint32, flags uint32, size *uintptr) (err error) {
+       r1, _, e1 := 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 LoadLibrary(libname string) (handle Handle, err error) {
        var _p0 *uint16
        _p0, err = UTF16PtrFromString(libname)
@@ -1099,6 +1115,14 @@ func UnmapViewOfFile(addr uintptr) (err error) {
        return
 }
 
+func updateProcThreadAttribute(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, flags uint32, attr uintptr, value uintptr, size uintptr, prevvalue uintptr, returnedsize *uintptr) (err error) {
+       r1, _, e1 := 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 VirtualLock(addr uintptr, length uintptr) (err error) {
        r1, _, e1 := Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0)
        if r1 == 0 {