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 7 package execenv
8 9 import (
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().
23 func 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