build: upgrade dependencies and build with go 1.21
This commit is contained in:
		
							
								
								
									
										2
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
// This package contains Win32 filesystem functionality.
 | 
			
		||||
package fs
 | 
			
		||||
							
								
								
									
										202
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
 | 
			
		||||
package fs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
 | 
			
		||||
	"github.com/Microsoft/go-winio/internal/stringbuffer"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go fs.go
 | 
			
		||||
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
 | 
			
		||||
//sys CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateFileW
 | 
			
		||||
 | 
			
		||||
const NullHandle windows.Handle = 0
 | 
			
		||||
 | 
			
		||||
// AccessMask defines standard, specific, and generic rights.
 | 
			
		||||
//
 | 
			
		||||
//	Bitmask:
 | 
			
		||||
//	 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
 | 
			
		||||
//	 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 | 
			
		||||
//	+---------------+---------------+-------------------------------+
 | 
			
		||||
//	|G|G|G|G|Resvd|A| StandardRights|         SpecificRights        |
 | 
			
		||||
//	|R|W|E|A|     |S|               |                               |
 | 
			
		||||
//	+-+-------------+---------------+-------------------------------+
 | 
			
		||||
//
 | 
			
		||||
//	GR     Generic Read
 | 
			
		||||
//	GW     Generic Write
 | 
			
		||||
//	GE     Generic Exectue
 | 
			
		||||
//	GA     Generic All
 | 
			
		||||
//	Resvd  Reserved
 | 
			
		||||
//	AS     Access Security System
 | 
			
		||||
//
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/secauthz/access-mask
 | 
			
		||||
//
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/secauthz/generic-access-rights
 | 
			
		||||
//
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/fileio/file-access-rights-constants
 | 
			
		||||
type AccessMask = windows.ACCESS_MASK
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const (
 | 
			
		||||
	// Not actually any.
 | 
			
		||||
	//
 | 
			
		||||
	// For CreateFile: "query certain metadata such as file, directory, or device attributes without accessing that file or device"
 | 
			
		||||
	// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#parameters
 | 
			
		||||
	FILE_ANY_ACCESS AccessMask = 0
 | 
			
		||||
 | 
			
		||||
	// Specific Object Access
 | 
			
		||||
	// from ntioapi.h
 | 
			
		||||
 | 
			
		||||
	FILE_READ_DATA      AccessMask = (0x0001) // file & pipe
 | 
			
		||||
	FILE_LIST_DIRECTORY AccessMask = (0x0001) // directory
 | 
			
		||||
 | 
			
		||||
	FILE_WRITE_DATA AccessMask = (0x0002) // file & pipe
 | 
			
		||||
	FILE_ADD_FILE   AccessMask = (0x0002) // directory
 | 
			
		||||
 | 
			
		||||
	FILE_APPEND_DATA          AccessMask = (0x0004) // file
 | 
			
		||||
	FILE_ADD_SUBDIRECTORY     AccessMask = (0x0004) // directory
 | 
			
		||||
	FILE_CREATE_PIPE_INSTANCE AccessMask = (0x0004) // named pipe
 | 
			
		||||
 | 
			
		||||
	FILE_READ_EA         AccessMask = (0x0008) // file & directory
 | 
			
		||||
	FILE_READ_PROPERTIES AccessMask = FILE_READ_EA
 | 
			
		||||
 | 
			
		||||
	FILE_WRITE_EA         AccessMask = (0x0010) // file & directory
 | 
			
		||||
	FILE_WRITE_PROPERTIES AccessMask = FILE_WRITE_EA
 | 
			
		||||
 | 
			
		||||
	FILE_EXECUTE  AccessMask = (0x0020) // file
 | 
			
		||||
	FILE_TRAVERSE AccessMask = (0x0020) // directory
 | 
			
		||||
 | 
			
		||||
	FILE_DELETE_CHILD AccessMask = (0x0040) // directory
 | 
			
		||||
 | 
			
		||||
	FILE_READ_ATTRIBUTES AccessMask = (0x0080) // all
 | 
			
		||||
 | 
			
		||||
	FILE_WRITE_ATTRIBUTES AccessMask = (0x0100) // all
 | 
			
		||||
 | 
			
		||||
	FILE_ALL_ACCESS      AccessMask = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
 | 
			
		||||
	FILE_GENERIC_READ    AccessMask = (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE)
 | 
			
		||||
	FILE_GENERIC_WRITE   AccessMask = (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE)
 | 
			
		||||
	FILE_GENERIC_EXECUTE AccessMask = (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE)
 | 
			
		||||
 | 
			
		||||
	SPECIFIC_RIGHTS_ALL AccessMask = 0x0000FFFF
 | 
			
		||||
 | 
			
		||||
	// Standard Access
 | 
			
		||||
	// from ntseapi.h
 | 
			
		||||
 | 
			
		||||
	DELETE       AccessMask = 0x0001_0000
 | 
			
		||||
	READ_CONTROL AccessMask = 0x0002_0000
 | 
			
		||||
	WRITE_DAC    AccessMask = 0x0004_0000
 | 
			
		||||
	WRITE_OWNER  AccessMask = 0x0008_0000
 | 
			
		||||
	SYNCHRONIZE  AccessMask = 0x0010_0000
 | 
			
		||||
 | 
			
		||||
	STANDARD_RIGHTS_REQUIRED AccessMask = 0x000F_0000
 | 
			
		||||
 | 
			
		||||
	STANDARD_RIGHTS_READ    AccessMask = READ_CONTROL
 | 
			
		||||
	STANDARD_RIGHTS_WRITE   AccessMask = READ_CONTROL
 | 
			
		||||
	STANDARD_RIGHTS_EXECUTE AccessMask = READ_CONTROL
 | 
			
		||||
 | 
			
		||||
	STANDARD_RIGHTS_ALL AccessMask = 0x001F_0000
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type FileShareMode uint32
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const (
 | 
			
		||||
	FILE_SHARE_NONE        FileShareMode = 0x00
 | 
			
		||||
	FILE_SHARE_READ        FileShareMode = 0x01
 | 
			
		||||
	FILE_SHARE_WRITE       FileShareMode = 0x02
 | 
			
		||||
	FILE_SHARE_DELETE      FileShareMode = 0x04
 | 
			
		||||
	FILE_SHARE_VALID_FLAGS FileShareMode = 0x07
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type FileCreationDisposition uint32
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const (
 | 
			
		||||
	// from winbase.h
 | 
			
		||||
 | 
			
		||||
	CREATE_NEW        FileCreationDisposition = 0x01
 | 
			
		||||
	CREATE_ALWAYS     FileCreationDisposition = 0x02
 | 
			
		||||
	OPEN_EXISTING     FileCreationDisposition = 0x03
 | 
			
		||||
	OPEN_ALWAYS       FileCreationDisposition = 0x04
 | 
			
		||||
	TRUNCATE_EXISTING FileCreationDisposition = 0x05
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CreateFile and co. take flags or attributes together as one parameter.
 | 
			
		||||
// Define alias until we can use generics to allow both
 | 
			
		||||
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
 | 
			
		||||
type FileFlagOrAttribute uint32
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const ( // from winnt.h
 | 
			
		||||
	FILE_FLAG_WRITE_THROUGH       FileFlagOrAttribute = 0x8000_0000
 | 
			
		||||
	FILE_FLAG_OVERLAPPED          FileFlagOrAttribute = 0x4000_0000
 | 
			
		||||
	FILE_FLAG_NO_BUFFERING        FileFlagOrAttribute = 0x2000_0000
 | 
			
		||||
	FILE_FLAG_RANDOM_ACCESS       FileFlagOrAttribute = 0x1000_0000
 | 
			
		||||
	FILE_FLAG_SEQUENTIAL_SCAN     FileFlagOrAttribute = 0x0800_0000
 | 
			
		||||
	FILE_FLAG_DELETE_ON_CLOSE     FileFlagOrAttribute = 0x0400_0000
 | 
			
		||||
	FILE_FLAG_BACKUP_SEMANTICS    FileFlagOrAttribute = 0x0200_0000
 | 
			
		||||
	FILE_FLAG_POSIX_SEMANTICS     FileFlagOrAttribute = 0x0100_0000
 | 
			
		||||
	FILE_FLAG_OPEN_REPARSE_POINT  FileFlagOrAttribute = 0x0020_0000
 | 
			
		||||
	FILE_FLAG_OPEN_NO_RECALL      FileFlagOrAttribute = 0x0010_0000
 | 
			
		||||
	FILE_FLAG_FIRST_PIPE_INSTANCE FileFlagOrAttribute = 0x0008_0000
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type FileSQSFlag = FileFlagOrAttribute
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const ( // from winbase.h
 | 
			
		||||
	SECURITY_ANONYMOUS      FileSQSFlag = FileSQSFlag(SecurityAnonymous << 16)
 | 
			
		||||
	SECURITY_IDENTIFICATION FileSQSFlag = FileSQSFlag(SecurityIdentification << 16)
 | 
			
		||||
	SECURITY_IMPERSONATION  FileSQSFlag = FileSQSFlag(SecurityImpersonation << 16)
 | 
			
		||||
	SECURITY_DELEGATION     FileSQSFlag = FileSQSFlag(SecurityDelegation << 16)
 | 
			
		||||
 | 
			
		||||
	SECURITY_SQOS_PRESENT     FileSQSFlag = 0x00100000
 | 
			
		||||
	SECURITY_VALID_SQOS_FLAGS FileSQSFlag = 0x001F0000
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetFinalPathNameByHandle flags
 | 
			
		||||
//
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew#parameters
 | 
			
		||||
type GetFinalPathFlag uint32
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const (
 | 
			
		||||
	GetFinalPathDefaultFlag GetFinalPathFlag = 0x0
 | 
			
		||||
 | 
			
		||||
	FILE_NAME_NORMALIZED GetFinalPathFlag = 0x0
 | 
			
		||||
	FILE_NAME_OPENED     GetFinalPathFlag = 0x8
 | 
			
		||||
 | 
			
		||||
	VOLUME_NAME_DOS  GetFinalPathFlag = 0x0
 | 
			
		||||
	VOLUME_NAME_GUID GetFinalPathFlag = 0x1
 | 
			
		||||
	VOLUME_NAME_NT   GetFinalPathFlag = 0x2
 | 
			
		||||
	VOLUME_NAME_NONE GetFinalPathFlag = 0x4
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// getFinalPathNameByHandle facilitates calling the Windows API GetFinalPathNameByHandle
 | 
			
		||||
// with the given handle and flags. It transparently takes care of creating a buffer of the
 | 
			
		||||
// correct size for the call.
 | 
			
		||||
//
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew
 | 
			
		||||
func GetFinalPathNameByHandle(h windows.Handle, flags GetFinalPathFlag) (string, error) {
 | 
			
		||||
	b := stringbuffer.NewWString()
 | 
			
		||||
	//TODO: can loop infinitely if Win32 keeps returning the same (or a larger) n?
 | 
			
		||||
	for {
 | 
			
		||||
		n, err := windows.GetFinalPathNameByHandle(h, b.Pointer(), b.Cap(), uint32(flags))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
		// If the buffer wasn't large enough, n will be the total size needed (including null terminator).
 | 
			
		||||
		// Resize and try again.
 | 
			
		||||
		if n > b.Cap() {
 | 
			
		||||
			b.ResizeTo(n)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// If the buffer is large enough, n will be the size not including the null terminator.
 | 
			
		||||
		// Convert to a Go string and return.
 | 
			
		||||
		return b.String(), nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/security.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/security.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
package fs
 | 
			
		||||
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level
 | 
			
		||||
type SecurityImpersonationLevel int32 // C default enums underlying type is `int`, which is Go `int32`
 | 
			
		||||
 | 
			
		||||
// Impersonation levels
 | 
			
		||||
const (
 | 
			
		||||
	SecurityAnonymous      SecurityImpersonationLevel = 0
 | 
			
		||||
	SecurityIdentification SecurityImpersonationLevel = 1
 | 
			
		||||
	SecurityImpersonation  SecurityImpersonationLevel = 2
 | 
			
		||||
	SecurityDelegation     SecurityImpersonationLevel = 3
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										64
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
 | 
			
		||||
// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package fs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ unsafe.Pointer
 | 
			
		||||
 | 
			
		||||
// Do the interface allocations only once for common
 | 
			
		||||
// Errno values.
 | 
			
		||||
const (
 | 
			
		||||
	errnoERROR_IO_PENDING = 997
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
 | 
			
		||||
	errERROR_EINVAL     error = syscall.EINVAL
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// errnoErr returns common boxed Errno values, to prevent
 | 
			
		||||
// allocations at runtime.
 | 
			
		||||
func errnoErr(e syscall.Errno) error {
 | 
			
		||||
	switch e {
 | 
			
		||||
	case 0:
 | 
			
		||||
		return errERROR_EINVAL
 | 
			
		||||
	case errnoERROR_IO_PENDING:
 | 
			
		||||
		return errERROR_IO_PENDING
 | 
			
		||||
	}
 | 
			
		||||
	// TODO: add more here, after collecting data on the common
 | 
			
		||||
	// error values see on Windows. (perhaps when running
 | 
			
		||||
	// all.bat?)
 | 
			
		||||
	return e
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
 | 
			
		||||
 | 
			
		||||
	procCreateFileW = modkernel32.NewProc("CreateFileW")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {
 | 
			
		||||
	var _p0 *uint16
 | 
			
		||||
	_p0, err = syscall.UTF16PtrFromString(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return _CreateFile(_p0, access, mode, sa, createmode, attrs, templatefile)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func _CreateFile(name *uint16, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {
 | 
			
		||||
	r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
 | 
			
		||||
	handle = windows.Handle(r0)
 | 
			
		||||
	if handle == windows.InvalidHandle {
 | 
			
		||||
		err = errnoErr(e1)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
package socket
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// RawSockaddr allows structs to be used with [Bind] and [ConnectEx]. The
 | 
			
		||||
// struct must meet the Win32 sockaddr requirements specified here:
 | 
			
		||||
// https://docs.microsoft.com/en-us/windows/win32/winsock/sockaddr-2
 | 
			
		||||
//
 | 
			
		||||
// Specifically, the struct size must be least larger than an int16 (unsigned short)
 | 
			
		||||
// for the address family.
 | 
			
		||||
type RawSockaddr interface {
 | 
			
		||||
	// Sockaddr returns a pointer to the RawSockaddr and its struct size, allowing
 | 
			
		||||
	// for the RawSockaddr's data to be overwritten by syscalls (if necessary).
 | 
			
		||||
	//
 | 
			
		||||
	// It is the callers responsibility to validate that the values are valid; invalid
 | 
			
		||||
	// pointers or size can cause a panic.
 | 
			
		||||
	Sockaddr() (unsafe.Pointer, int32, error)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										179
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/socket.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/socket.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
 | 
			
		||||
package socket
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"github.com/Microsoft/go-winio/pkg/guid"
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go socket.go
 | 
			
		||||
 | 
			
		||||
//sys getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getsockname
 | 
			
		||||
//sys getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getpeername
 | 
			
		||||
//sys bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socketError] = ws2_32.bind
 | 
			
		||||
 | 
			
		||||
const socketError = uintptr(^uint32(0))
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// todo(helsaawy): create custom error types to store the desired vs actual size and addr family?
 | 
			
		||||
 | 
			
		||||
	ErrBufferSize     = errors.New("buffer size")
 | 
			
		||||
	ErrAddrFamily     = errors.New("address family")
 | 
			
		||||
	ErrInvalidPointer = errors.New("invalid pointer")
 | 
			
		||||
	ErrSocketClosed   = fmt.Errorf("socket closed: %w", net.ErrClosed)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// todo(helsaawy): replace these with generics, ie: GetSockName[S RawSockaddr](s windows.Handle) (S, error)
 | 
			
		||||
 | 
			
		||||
// GetSockName writes the local address of socket s to the [RawSockaddr] rsa.
 | 
			
		||||
// If rsa is not large enough, the [windows.WSAEFAULT] is returned.
 | 
			
		||||
func GetSockName(s windows.Handle, rsa RawSockaddr) error {
 | 
			
		||||
	ptr, l, err := rsa.Sockaddr()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// although getsockname returns WSAEFAULT if the buffer is too small, it does not set
 | 
			
		||||
	// &l to the correct size, so--apart from doubling the buffer repeatedly--there is no remedy
 | 
			
		||||
	return getsockname(s, ptr, &l)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetPeerName returns the remote address the socket is connected to.
 | 
			
		||||
//
 | 
			
		||||
// See [GetSockName] for more information.
 | 
			
		||||
func GetPeerName(s windows.Handle, rsa RawSockaddr) error {
 | 
			
		||||
	ptr, l, err := rsa.Sockaddr()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return getpeername(s, ptr, &l)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Bind(s windows.Handle, rsa RawSockaddr) (err error) {
 | 
			
		||||
	ptr, l, err := rsa.Sockaddr()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return bind(s, ptr, l)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// "golang.org/x/sys/windows".ConnectEx and .Bind only accept internal implementations of the
 | 
			
		||||
// their sockaddr interface, so they cannot be used with HvsockAddr
 | 
			
		||||
// Replicate functionality here from
 | 
			
		||||
// https://cs.opensource.google/go/x/sys/+/master:windows/syscall_windows.go
 | 
			
		||||
 | 
			
		||||
// The function pointers to `AcceptEx`, `ConnectEx` and `GetAcceptExSockaddrs` must be loaded at
 | 
			
		||||
// runtime via a WSAIoctl call:
 | 
			
		||||
// https://docs.microsoft.com/en-us/windows/win32/api/Mswsock/nc-mswsock-lpfn_connectex#remarks
 | 
			
		||||
 | 
			
		||||
type runtimeFunc struct {
 | 
			
		||||
	id   guid.GUID
 | 
			
		||||
	once sync.Once
 | 
			
		||||
	addr uintptr
 | 
			
		||||
	err  error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *runtimeFunc) Load() error {
 | 
			
		||||
	f.once.Do(func() {
 | 
			
		||||
		var s windows.Handle
 | 
			
		||||
		s, f.err = windows.Socket(windows.AF_INET, windows.SOCK_STREAM, windows.IPPROTO_TCP)
 | 
			
		||||
		if f.err != nil {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		defer windows.CloseHandle(s) //nolint:errcheck
 | 
			
		||||
 | 
			
		||||
		var n uint32
 | 
			
		||||
		f.err = windows.WSAIoctl(s,
 | 
			
		||||
			windows.SIO_GET_EXTENSION_FUNCTION_POINTER,
 | 
			
		||||
			(*byte)(unsafe.Pointer(&f.id)),
 | 
			
		||||
			uint32(unsafe.Sizeof(f.id)),
 | 
			
		||||
			(*byte)(unsafe.Pointer(&f.addr)),
 | 
			
		||||
			uint32(unsafe.Sizeof(f.addr)),
 | 
			
		||||
			&n,
 | 
			
		||||
			nil, // overlapped
 | 
			
		||||
			0,   // completionRoutine
 | 
			
		||||
		)
 | 
			
		||||
	})
 | 
			
		||||
	return f.err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// todo: add `AcceptEx` and `GetAcceptExSockaddrs`
 | 
			
		||||
	WSAID_CONNECTEX = guid.GUID{ //revive:disable-line:var-naming ALL_CAPS
 | 
			
		||||
		Data1: 0x25a207b9,
 | 
			
		||||
		Data2: 0xddf3,
 | 
			
		||||
		Data3: 0x4660,
 | 
			
		||||
		Data4: [8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	connectExFunc = runtimeFunc{id: WSAID_CONNECTEX}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func ConnectEx(
 | 
			
		||||
	fd windows.Handle,
 | 
			
		||||
	rsa RawSockaddr,
 | 
			
		||||
	sendBuf *byte,
 | 
			
		||||
	sendDataLen uint32,
 | 
			
		||||
	bytesSent *uint32,
 | 
			
		||||
	overlapped *windows.Overlapped,
 | 
			
		||||
) error {
 | 
			
		||||
	if err := connectExFunc.Load(); err != nil {
 | 
			
		||||
		return fmt.Errorf("failed to load ConnectEx function pointer: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	ptr, n, err := rsa.Sockaddr()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BOOL LpfnConnectex(
 | 
			
		||||
//   [in]           SOCKET s,
 | 
			
		||||
//   [in]           const sockaddr *name,
 | 
			
		||||
//   [in]           int namelen,
 | 
			
		||||
//   [in, optional] PVOID lpSendBuffer,
 | 
			
		||||
//   [in]           DWORD dwSendDataLength,
 | 
			
		||||
//   [out]          LPDWORD lpdwBytesSent,
 | 
			
		||||
//   [in]           LPOVERLAPPED lpOverlapped
 | 
			
		||||
// )
 | 
			
		||||
 | 
			
		||||
func connectEx(
 | 
			
		||||
	s windows.Handle,
 | 
			
		||||
	name unsafe.Pointer,
 | 
			
		||||
	namelen int32,
 | 
			
		||||
	sendBuf *byte,
 | 
			
		||||
	sendDataLen uint32,
 | 
			
		||||
	bytesSent *uint32,
 | 
			
		||||
	overlapped *windows.Overlapped,
 | 
			
		||||
) (err error) {
 | 
			
		||||
	// todo: after upgrading to 1.18, switch from syscall.Syscall9 to syscall.SyscallN
 | 
			
		||||
	r1, _, e1 := syscall.Syscall9(connectExFunc.addr,
 | 
			
		||||
		7,
 | 
			
		||||
		uintptr(s),
 | 
			
		||||
		uintptr(name),
 | 
			
		||||
		uintptr(namelen),
 | 
			
		||||
		uintptr(unsafe.Pointer(sendBuf)),
 | 
			
		||||
		uintptr(sendDataLen),
 | 
			
		||||
		uintptr(unsafe.Pointer(bytesSent)),
 | 
			
		||||
		uintptr(unsafe.Pointer(overlapped)),
 | 
			
		||||
		0,
 | 
			
		||||
		0)
 | 
			
		||||
	if r1 == 0 {
 | 
			
		||||
		if e1 != 0 {
 | 
			
		||||
			err = error(e1)
 | 
			
		||||
		} else {
 | 
			
		||||
			err = syscall.EINVAL
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
 | 
			
		||||
// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package socket
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ unsafe.Pointer
 | 
			
		||||
 | 
			
		||||
// Do the interface allocations only once for common
 | 
			
		||||
// Errno values.
 | 
			
		||||
const (
 | 
			
		||||
	errnoERROR_IO_PENDING = 997
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
 | 
			
		||||
	errERROR_EINVAL     error = syscall.EINVAL
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// errnoErr returns common boxed Errno values, to prevent
 | 
			
		||||
// allocations at runtime.
 | 
			
		||||
func errnoErr(e syscall.Errno) error {
 | 
			
		||||
	switch e {
 | 
			
		||||
	case 0:
 | 
			
		||||
		return errERROR_EINVAL
 | 
			
		||||
	case errnoERROR_IO_PENDING:
 | 
			
		||||
		return errERROR_IO_PENDING
 | 
			
		||||
	}
 | 
			
		||||
	// TODO: add more here, after collecting data on the common
 | 
			
		||||
	// error values see on Windows. (perhaps when running
 | 
			
		||||
	// all.bat?)
 | 
			
		||||
	return e
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
 | 
			
		||||
 | 
			
		||||
	procbind        = modws2_32.NewProc("bind")
 | 
			
		||||
	procgetpeername = modws2_32.NewProc("getpeername")
 | 
			
		||||
	procgetsockname = modws2_32.NewProc("getsockname")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) {
 | 
			
		||||
	r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
 | 
			
		||||
	if r1 == socketError {
 | 
			
		||||
		err = errnoErr(e1)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {
 | 
			
		||||
	r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
 | 
			
		||||
	if r1 == socketError {
 | 
			
		||||
		err = errnoErr(e1)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {
 | 
			
		||||
	r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
 | 
			
		||||
	if r1 == socketError {
 | 
			
		||||
		err = errnoErr(e1)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										132
									
								
								vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
package stringbuffer
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sync"
 | 
			
		||||
	"unicode/utf16"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TODO: worth exporting and using in mkwinsyscall?
 | 
			
		||||
 | 
			
		||||
// Uint16BufferSize is the buffer size in the pool, chosen somewhat arbitrarily to accommodate
 | 
			
		||||
// large path strings:
 | 
			
		||||
// MAX_PATH (260) + size of volume GUID prefix (49) + null terminator = 310.
 | 
			
		||||
const MinWStringCap = 310
 | 
			
		||||
 | 
			
		||||
// use *[]uint16 since []uint16 creates an extra allocation where the slice header
 | 
			
		||||
// is copied to heap and then referenced via pointer in the interface header that sync.Pool
 | 
			
		||||
// stores.
 | 
			
		||||
var pathPool = sync.Pool{ // if go1.18+ adds Pool[T], use that to store []uint16 directly
 | 
			
		||||
	New: func() interface{} {
 | 
			
		||||
		b := make([]uint16, MinWStringCap)
 | 
			
		||||
		return &b
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newBuffer() []uint16 { return *(pathPool.Get().(*[]uint16)) }
 | 
			
		||||
 | 
			
		||||
// freeBuffer copies the slice header data, and puts a pointer to that in the pool.
 | 
			
		||||
// This avoids taking a pointer to the slice header in WString, which can be set to nil.
 | 
			
		||||
func freeBuffer(b []uint16) { pathPool.Put(&b) }
 | 
			
		||||
 | 
			
		||||
// WString is a wide string buffer ([]uint16) meant for storing UTF-16 encoded strings
 | 
			
		||||
// for interacting with Win32 APIs.
 | 
			
		||||
// Sizes are specified as uint32 and not int.
 | 
			
		||||
//
 | 
			
		||||
// It is not thread safe.
 | 
			
		||||
type WString struct {
 | 
			
		||||
	// type-def allows casting to []uint16 directly, use struct to prevent that and allow adding fields in the future.
 | 
			
		||||
 | 
			
		||||
	// raw buffer
 | 
			
		||||
	b []uint16
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewWString returns a [WString] allocated from a shared pool with an
 | 
			
		||||
// initial capacity of at least [MinWStringCap].
 | 
			
		||||
// Since the buffer may have been previously used, its contents are not guaranteed to be empty.
 | 
			
		||||
//
 | 
			
		||||
// The buffer should be freed via [WString.Free]
 | 
			
		||||
func NewWString() *WString {
 | 
			
		||||
	return &WString{
 | 
			
		||||
		b: newBuffer(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *WString) Free() {
 | 
			
		||||
	if b.empty() {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	freeBuffer(b.b)
 | 
			
		||||
	b.b = nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResizeTo grows the buffer to at least c and returns the new capacity, freeing the
 | 
			
		||||
// previous buffer back into pool.
 | 
			
		||||
func (b *WString) ResizeTo(c uint32) uint32 {
 | 
			
		||||
	// allready sufficient (or n is 0)
 | 
			
		||||
	if c <= b.Cap() {
 | 
			
		||||
		return b.Cap()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c <= MinWStringCap {
 | 
			
		||||
		c = MinWStringCap
 | 
			
		||||
	}
 | 
			
		||||
	// allocate at-least double buffer size, as is done in [bytes.Buffer] and other places
 | 
			
		||||
	if c <= 2*b.Cap() {
 | 
			
		||||
		c = 2 * b.Cap()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b2 := make([]uint16, c)
 | 
			
		||||
	if !b.empty() {
 | 
			
		||||
		copy(b2, b.b)
 | 
			
		||||
		freeBuffer(b.b)
 | 
			
		||||
	}
 | 
			
		||||
	b.b = b2
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Buffer returns the underlying []uint16 buffer.
 | 
			
		||||
func (b *WString) Buffer() []uint16 {
 | 
			
		||||
	if b.empty() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return b.b
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pointer returns a pointer to the first uint16 in the buffer.
 | 
			
		||||
// If the [WString.Free] has already been called, the pointer will be nil.
 | 
			
		||||
func (b *WString) Pointer() *uint16 {
 | 
			
		||||
	if b.empty() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return &b.b[0]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String returns the returns the UTF-8 encoding of the UTF-16 string in the buffer.
 | 
			
		||||
//
 | 
			
		||||
// It assumes that the data is null-terminated.
 | 
			
		||||
func (b *WString) String() string {
 | 
			
		||||
	// Using [windows.UTF16ToString] would require importing "golang.org/x/sys/windows"
 | 
			
		||||
	// and would make this code Windows-only, which makes no sense.
 | 
			
		||||
	// So copy UTF16ToString code into here.
 | 
			
		||||
	// If other windows-specific code is added, switch to [windows.UTF16ToString]
 | 
			
		||||
 | 
			
		||||
	s := b.b
 | 
			
		||||
	for i, v := range s {
 | 
			
		||||
		if v == 0 {
 | 
			
		||||
			s = s[:i]
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return string(utf16.Decode(s))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Cap returns the underlying buffer capacity.
 | 
			
		||||
func (b *WString) Cap() uint32 {
 | 
			
		||||
	if b.empty() {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	return b.cap()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *WString) cap() uint32 { return uint32(cap(b.b)) }
 | 
			
		||||
func (b *WString) empty() bool { return b == nil || b.cap() == 0 }
 | 
			
		||||
		Reference in New Issue
	
	Block a user