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