github.com/sandwichdev/go-internals@v0.0.0-20210605002614-12311ac6b2c5/syscall/execenv/execenv_windows.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build windows 6 7 package execenv 8 9 import ( 10 "syscall" 11 "unicode/utf16" 12 "unsafe" 13 14 "github.com/SandwichDev/go-internals/syscall/windows" 15 ) 16 17 // Default will return the default environment 18 // variables based on the process attributes 19 // provided. 20 // 21 // If the process attributes contain a token, then 22 // the environment variables will be sourced from 23 // the defaults for that user token, otherwise they 24 // will be sourced from syscall.Environ(). 25 func Default(sys *syscall.SysProcAttr) (env []string, err error) { 26 if sys == nil || sys.Token == 0 { 27 return syscall.Environ(), nil 28 } 29 var block *uint16 30 err = windows.CreateEnvironmentBlock(&block, sys.Token, false) 31 if err != nil { 32 return nil, err 33 } 34 defer windows.DestroyEnvironmentBlock(block) 35 blockp := uintptr(unsafe.Pointer(block)) 36 for { 37 38 // find NUL terminator 39 end := unsafe.Pointer(blockp) 40 for *(*uint16)(end) != 0 { 41 end = unsafe.Pointer(uintptr(end) + 2) 42 } 43 44 n := (uintptr(end) - uintptr(unsafe.Pointer(blockp))) / 2 45 if n == 0 { 46 // environment block ends with empty string 47 break 48 } 49 50 entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:n:n] 51 env = append(env, string(utf16.Decode(entry))) 52 blockp += 2 * (uintptr(len(entry)) + 1) 53 } 54 return 55 }