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//go:build windows 6 7package execenv 8 9import ( 10 "internal/syscall/windows" 11 "syscall" 12 "unsafe" 13) 14 15// Default will return the default environment 16// variables based on the process attributes 17// provided. 18// 19// If the process attributes contain a token, then 20// the environment variables will be sourced from 21// the defaults for that user token, otherwise they 22// will be sourced from syscall.Environ(). 23func Default(sys *syscall.SysProcAttr) (env []string, err error) { 24 if sys == nil || sys.Token == 0 { 25 return syscall.Environ(), nil 26 } 27 var blockp *uint16 28 err = windows.CreateEnvironmentBlock(&blockp, sys.Token, false) 29 if err != nil { 30 return nil, err 31 } 32 defer windows.DestroyEnvironmentBlock(blockp) 33 34 const size = unsafe.Sizeof(*blockp) 35 for *blockp != 0 { // environment block ends with empty string 36 // find NUL terminator 37 end := unsafe.Add(unsafe.Pointer(blockp), size) 38 for *(*uint16)(end) != 0 { 39 end = unsafe.Add(end, size) 40 } 41 42 entry := unsafe.Slice(blockp, (uintptr(end)-uintptr(unsafe.Pointer(blockp)))/2) 43 env = append(env, syscall.UTF16ToString(entry)) 44 blockp = (*uint16)(unsafe.Add(end, size)) 45 } 46 return 47} 48