blob: 2a89ed1f58f1c42c04ec88b384cfc8d6436f77aa [file] [log] [blame]
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build windows
package execenv
import (
"internal/syscall/windows"
"syscall"
"unsafe"
)
// Default will return the default environment
// variables based on the process attributes
// provided.
//
// If the process attributes contain a token, then
// the environment variables will be sourced from
// the defaults for that user token, otherwise they
// will be sourced from syscall.Environ().
func Default(sys *syscall.SysProcAttr) (env []string, err error) {
if sys == nil || sys.Token == 0 {
return syscall.Environ(), nil
}
var blockp *uint16
err = windows.CreateEnvironmentBlock(&blockp, sys.Token, false)
if err != nil {
return nil, err
}
defer windows.DestroyEnvironmentBlock(blockp)
const size = unsafe.Sizeof(*blockp)
for *blockp != 0 { // environment block ends with empty string
// find NUL terminator
end := unsafe.Add(unsafe.Pointer(blockp), size)
for *(*uint16)(end) != 0 {
end = unsafe.Add(end, size)
}
entry := unsafe.Slice(blockp, (uintptr(end)-uintptr(unsafe.Pointer(blockp)))/2)
env = append(env, syscall.UTF16ToString(entry))
blockp = (*uint16)(unsafe.Add(end, size))
}
return
}