func duplicateTokenEx(hExistingToken syscall.Token, dwDesiredAccess uint32, lpTokenAttributes uintptr, ImpersonationLevel uint32, TokenType uint32) (*syscall.Token, error) {
	var hNewtoken syscall.Token
	ret, _, errno := procDuplicateTokenEx.Call(
		uintptr(hExistingToken),
		uintptr(dwDesiredAccess),
		lpTokenAttributes,
		uintptr(ImpersonationLevel),
		uintptr(TokenType),
		uintptr(unsafe.Pointer(&hNewtoken)),
	)
	if err := testReturnCodeNonZero(ret, errno); err != nil {
		return nil, err
	}
	return &hNewtoken, nil
}
BOOL DuplicateTokenEx(
HANDLE                       hExistingToken,
DWORD                        dwDesiredAccess,
LPSECURITY_ATTRIBUTES        lpTokenAttributes,
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
TOKEN_TYPE                   TokenType,
PHANDLE                      phNewToken
);
https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-duplicatetokenex
package win32
import (
	"fmt"
	"strings"
	"syscall"
	"unsafe"
	"golang.org/x/sys/windows"
)
var (
	procCreateRestrictedToken   = advapi32DLL.NewProc("CreateRestrictedToken")
	procGetTokenInformation     = advapi32DLL.NewProc("GetTokenInformation")
	procSetTokenInformation     = advapi32DLL.NewProc("SetTokenInformation")
	procLogonUserW              = advapi32DLL.NewProc("LogonUserW")
	procLookupPrivilegeValue    = advapi32DLL.NewProc("LookupPrivilegeValue")
	procDuplicateTokenEx        = advapi32DLL.NewProc("DuplicateTokenEx")
	procImpersonateLoggedOnUser = advapi32DLL.NewProc("ImpersonateLoggedOnUser")
	procRevertToSelf            = advapi32DLL.NewProc("RevertToSelf")
)
type _LUID struct {
	LowPart  DWORD
	HighPart LONG
}
type _LUID_AND_ATTRIBUTES struct {
	LUID       _LUID
	Attributes DWORD
}
func lookupLUID(system *Text, name Text) (*_LUID, error) {
	var luid _LUID
	lpSystemName := system.WChars()
	lpName := name.WChars()
	ret, _, err := procLookupPrivilegeValue.Call(
		uintptr(unsafe.Pointer(lpSystemName)),
		uintptr(unsafe.Pointer(lpName)),
		uintptr(unsafe.Pointer(&luid)),
	)
	if ret == 0 {
		return nil, err
	}
	return &luid, nil
}
const (
	_LOGON32_LOGON_INTERACTIVE       uint32 = 2
	_LOGON32_LOGON_NETWORK           uint32 = 3
	_LOGON32_LOGON_BATCH             uint32 = 4
	_LOGON32_LOGON_SERVICE           uint32 = 5
	_LOGON32_LOGON_UNLOCK            uint32 = 7
	_LOGON32_LOGON_NETWORK_CLEARTEXT uint32 = 8
	_LOGON32_LOGON_NEW_CREDENTIALS   uint32 = 9
)
const (
	_LOGON32_PROVIDER_DEFAULT uint32 = 0
	_LOGON32_PROVIDER_WINNT35 uint32 = 1
	_LOGON32_PROVIDER_WINNT40 uint32 = 2
	_LOGON32_PROVIDER_WINNT50 uint32 = 3
	_LOGON32_PROVIDER_VIRTUAL uint32 = 4
)
func logonUser(user, domain, password *uint16, logonType uint32, logonProvider uint32) (*syscall.Token, error) {
	var hToken syscall.Token
	ret, _, errno := procLogonUserW.Call(
		uintptr(unsafe.Pointer(user)),
		uintptr(unsafe.Pointer(domain)),
		uintptr(unsafe.Pointer(password)),
		uintptr(logonType),
		uintptr(logonProvider),
		uintptr(unsafe.Pointer(&hToken)),
	)
	if err := testReturnCodeNonZero(ret, errno); err != nil {
		return nil, err
	}
	return &hToken, nil
}
func setTokenInformation(hToken syscall.Token, tokenInformationClass uint32, tokenInformation uintptr, tokenInformationLength uint32) error {
	ret, _, err := procSetTokenInformation.Call(
		uintptr(hToken),
		uintptr(tokenInformationClass),
		tokenInformation,
		uintptr(tokenInformationLength),
	)
	return testReturnCodeNonZero(ret, err)
}
func getTokenInformation(hToken syscall.Token, tokenInformationClass uint32) (unsafe.Pointer, error) {
	n := uint32(4)
	buf := make([]byte, n)
	for {
		ret, _, errno := procGetTokenInformation.Call(
			uintptr(hToken),
			uintptr(tokenInformationClass),
			uintptr(unsafe.Pointer(&buf[0])),
			uintptr(len(buf)),
			uintptr(unsafe.Pointer(&n)),
		)
		if errno == syscall.ERROR_INSUFFICIENT_BUFFER {  
			continue
		}
		if err := testReturnCodeNonZero(ret, errno); err != nil {
			return nil, err
		}
		return unsafe.Pointer(&buf[0]), nil
	}
}