github.com/SandwichDev/go-internals@v0.0.0-20210605002614-12311ac6b2c5/syscall/windows/syscall_windows.go (about)

     1  // Copyright 2014 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  package windows
     6  
     7  import (
     8  	"sync"
     9  	"syscall"
    10  	"unicode/utf16"
    11  	"unsafe"
    12  
    13  	"github.com/SandwichDev/go-internals/unsafeheader"
    14  )
    15  
    16  // UTF16PtrToString is like UTF16ToString, but takes *uint16
    17  // as a parameter instead of []uint16.
    18  func UTF16PtrToString(p *uint16) string {
    19  	if p == nil {
    20  		return ""
    21  	}
    22  	// Find NUL terminator.
    23  	end := unsafe.Pointer(p)
    24  	n := 0
    25  	for *(*uint16)(end) != 0 {
    26  		end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p))
    27  		n++
    28  	}
    29  	// Turn *uint16 into []uint16.
    30  	var s []uint16
    31  	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
    32  	hdr.Data = unsafe.Pointer(p)
    33  	hdr.Cap = n
    34  	hdr.Len = n
    35  	// Decode []uint16 into string.
    36  	return string(utf16.Decode(s))
    37  }
    38  
    39  const (
    40  	ERROR_SHARING_VIOLATION      syscall.Errno = 32
    41  	ERROR_LOCK_VIOLATION         syscall.Errno = 33
    42  	ERROR_NOT_SUPPORTED          syscall.Errno = 50
    43  	ERROR_CALL_NOT_IMPLEMENTED   syscall.Errno = 120
    44  	ERROR_INVALID_NAME           syscall.Errno = 123
    45  	ERROR_LOCK_FAILED            syscall.Errno = 167
    46  	ERROR_NO_UNICODE_TRANSLATION syscall.Errno = 1113
    47  )
    48  
    49  const GAA_FLAG_INCLUDE_PREFIX = 0x00000010
    50  
    51  const (
    52  	IF_TYPE_OTHER              = 1
    53  	IF_TYPE_ETHERNET_CSMACD    = 6
    54  	IF_TYPE_ISO88025_TOKENRING = 9
    55  	IF_TYPE_PPP                = 23
    56  	IF_TYPE_SOFTWARE_LOOPBACK  = 24
    57  	IF_TYPE_ATM                = 37
    58  	IF_TYPE_IEEE80211          = 71
    59  	IF_TYPE_TUNNEL             = 131
    60  	IF_TYPE_IEEE1394           = 144
    61  )
    62  
    63  type SocketAddress struct {
    64  	Sockaddr       *syscall.RawSockaddrAny
    65  	SockaddrLength int32
    66  }
    67  
    68  type IpAdapterUnicastAddress struct {
    69  	Length             uint32
    70  	Flags              uint32
    71  	Next               *IpAdapterUnicastAddress
    72  	Address            SocketAddress
    73  	PrefixOrigin       int32
    74  	SuffixOrigin       int32
    75  	DadState           int32
    76  	ValidLifetime      uint32
    77  	PreferredLifetime  uint32
    78  	LeaseLifetime      uint32
    79  	OnLinkPrefixLength uint8
    80  }
    81  
    82  type IpAdapterAnycastAddress struct {
    83  	Length  uint32
    84  	Flags   uint32
    85  	Next    *IpAdapterAnycastAddress
    86  	Address SocketAddress
    87  }
    88  
    89  type IpAdapterMulticastAddress struct {
    90  	Length  uint32
    91  	Flags   uint32
    92  	Next    *IpAdapterMulticastAddress
    93  	Address SocketAddress
    94  }
    95  
    96  type IpAdapterDnsServerAdapter struct {
    97  	Length   uint32
    98  	Reserved uint32
    99  	Next     *IpAdapterDnsServerAdapter
   100  	Address  SocketAddress
   101  }
   102  
   103  type IpAdapterPrefix struct {
   104  	Length       uint32
   105  	Flags        uint32
   106  	Next         *IpAdapterPrefix
   107  	Address      SocketAddress
   108  	PrefixLength uint32
   109  }
   110  
   111  type IpAdapterAddresses struct {
   112  	Length                uint32
   113  	IfIndex               uint32
   114  	Next                  *IpAdapterAddresses
   115  	AdapterName           *byte
   116  	FirstUnicastAddress   *IpAdapterUnicastAddress
   117  	FirstAnycastAddress   *IpAdapterAnycastAddress
   118  	FirstMulticastAddress *IpAdapterMulticastAddress
   119  	FirstDnsServerAddress *IpAdapterDnsServerAdapter
   120  	DnsSuffix             *uint16
   121  	Description           *uint16
   122  	FriendlyName          *uint16
   123  	PhysicalAddress       [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
   124  	PhysicalAddressLength uint32
   125  	Flags                 uint32
   126  	Mtu                   uint32
   127  	IfType                uint32
   128  	OperStatus            uint32
   129  	Ipv6IfIndex           uint32
   130  	ZoneIndices           [16]uint32
   131  	FirstPrefix           *IpAdapterPrefix
   132  	/* more fields might be present here. */
   133  }
   134  
   135  type FILE_BASIC_INFO struct {
   136  	CreationTime   syscall.Filetime
   137  	LastAccessTime syscall.Filetime
   138  	LastWriteTime  syscall.Filetime
   139  	ChangedTime    syscall.Filetime
   140  	FileAttributes uint32
   141  }
   142  
   143  const (
   144  	IfOperStatusUp             = 1
   145  	IfOperStatusDown           = 2
   146  	IfOperStatusTesting        = 3
   147  	IfOperStatusUnknown        = 4
   148  	IfOperStatusDormant        = 5
   149  	IfOperStatusNotPresent     = 6
   150  	IfOperStatusLowerLayerDown = 7
   151  )
   152  
   153  //sys	GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses
   154  //sys	GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
   155  //sys	MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW
   156  //sys	GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
   157  //sys	SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) = kernel32.SetFileInformationByHandle
   158  
   159  const (
   160  	WSA_FLAG_OVERLAPPED        = 0x01
   161  	WSA_FLAG_NO_HANDLE_INHERIT = 0x80
   162  
   163  	WSAEMSGSIZE syscall.Errno = 10040
   164  
   165  	MSG_PEEK   = 0x2
   166  	MSG_TRUNC  = 0x0100
   167  	MSG_CTRUNC = 0x0200
   168  
   169  	socket_error = uintptr(^uint32(0))
   170  )
   171  
   172  var WSAID_WSASENDMSG = syscall.GUID{
   173  	Data1: 0xa441e712,
   174  	Data2: 0x754f,
   175  	Data3: 0x43ca,
   176  	Data4: [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d},
   177  }
   178  
   179  var WSAID_WSARECVMSG = syscall.GUID{
   180  	Data1: 0xf689d7c8,
   181  	Data2: 0x6f1f,
   182  	Data3: 0x436b,
   183  	Data4: [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22},
   184  }
   185  
   186  var sendRecvMsgFunc struct {
   187  	once     sync.Once
   188  	sendAddr uintptr
   189  	recvAddr uintptr
   190  	err      error
   191  }
   192  
   193  type WSAMsg struct {
   194  	Name        syscall.Pointer
   195  	Namelen     int32
   196  	Buffers     *syscall.WSABuf
   197  	BufferCount uint32
   198  	Control     syscall.WSABuf
   199  	Flags       uint32
   200  }
   201  
   202  //sys	WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = ws2_32.WSASocketW
   203  
   204  func loadWSASendRecvMsg() error {
   205  	sendRecvMsgFunc.once.Do(func() {
   206  		var s syscall.Handle
   207  		s, sendRecvMsgFunc.err = syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
   208  		if sendRecvMsgFunc.err != nil {
   209  			return
   210  		}
   211  		defer syscall.CloseHandle(s)
   212  		var n uint32
   213  		sendRecvMsgFunc.err = syscall.WSAIoctl(s,
   214  			syscall.SIO_GET_EXTENSION_FUNCTION_POINTER,
   215  			(*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)),
   216  			uint32(unsafe.Sizeof(WSAID_WSARECVMSG)),
   217  			(*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)),
   218  			uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)),
   219  			&n, nil, 0)
   220  		if sendRecvMsgFunc.err != nil {
   221  			return
   222  		}
   223  		sendRecvMsgFunc.err = syscall.WSAIoctl(s,
   224  			syscall.SIO_GET_EXTENSION_FUNCTION_POINTER,
   225  			(*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)),
   226  			uint32(unsafe.Sizeof(WSAID_WSASENDMSG)),
   227  			(*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)),
   228  			uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)),
   229  			&n, nil, 0)
   230  	})
   231  	return sendRecvMsgFunc.err
   232  }
   233  
   234  func WSASendMsg(fd syscall.Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *syscall.Overlapped, croutine *byte) error {
   235  	err := loadWSASendRecvMsg()
   236  	if err != nil {
   237  		return err
   238  	}
   239  	r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
   240  	if r1 == socket_error {
   241  		if e1 != 0 {
   242  			err = errnoErr(e1)
   243  		} else {
   244  			err = syscall.EINVAL
   245  		}
   246  	}
   247  	return err
   248  }
   249  
   250  func WSARecvMsg(fd syscall.Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *syscall.Overlapped, croutine *byte) error {
   251  	err := loadWSASendRecvMsg()
   252  	if err != nil {
   253  		return err
   254  	}
   255  	r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0)
   256  	if r1 == socket_error {
   257  		if e1 != 0 {
   258  			err = errnoErr(e1)
   259  		} else {
   260  			err = syscall.EINVAL
   261  		}
   262  	}
   263  	return err
   264  }
   265  
   266  const (
   267  	ComputerNameNetBIOS                   = 0
   268  	ComputerNameDnsHostname               = 1
   269  	ComputerNameDnsDomain                 = 2
   270  	ComputerNameDnsFullyQualified         = 3
   271  	ComputerNamePhysicalNetBIOS           = 4
   272  	ComputerNamePhysicalDnsHostname       = 5
   273  	ComputerNamePhysicalDnsDomain         = 6
   274  	ComputerNamePhysicalDnsFullyQualified = 7
   275  	ComputerNameMax                       = 8
   276  
   277  	MOVEFILE_REPLACE_EXISTING      = 0x1
   278  	MOVEFILE_COPY_ALLOWED          = 0x2
   279  	MOVEFILE_DELAY_UNTIL_REBOOT    = 0x4
   280  	MOVEFILE_WRITE_THROUGH         = 0x8
   281  	MOVEFILE_CREATE_HARDLINK       = 0x10
   282  	MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
   283  )
   284  
   285  func Rename(oldpath, newpath string) error {
   286  	from, err := syscall.UTF16PtrFromString(oldpath)
   287  	if err != nil {
   288  		return err
   289  	}
   290  	to, err := syscall.UTF16PtrFromString(newpath)
   291  	if err != nil {
   292  		return err
   293  	}
   294  	return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING)
   295  }
   296  
   297  //sys LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.LockFileEx
   298  //sys UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.UnlockFileEx
   299  
   300  const (
   301  	LOCKFILE_FAIL_IMMEDIATELY = 0x00000001
   302  	LOCKFILE_EXCLUSIVE_LOCK   = 0x00000002
   303  )
   304  
   305  const MB_ERR_INVALID_CHARS = 8
   306  
   307  //sys	GetACP() (acp uint32) = kernel32.GetACP
   308  //sys	GetConsoleCP() (ccp uint32) = kernel32.GetConsoleCP
   309  //sys	MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
   310  //sys	GetCurrentThread() (pseudoHandle syscall.Handle, err error) = kernel32.GetCurrentThread
   311  
   312  const STYPE_DISKTREE = 0x00
   313  
   314  type SHARE_INFO_2 struct {
   315  	Netname     *uint16
   316  	Type        uint32
   317  	Remark      *uint16
   318  	Permissions uint32
   319  	MaxUses     uint32
   320  	CurrentUses uint32
   321  	Path        *uint16
   322  	Passwd      *uint16
   323  }
   324  
   325  //sys  NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) = netapi32.NetShareAdd
   326  //sys  NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) = netapi32.NetShareDel
   327  
   328  const (
   329  	FILE_NAME_NORMALIZED = 0x0
   330  	FILE_NAME_OPENED     = 0x8
   331  
   332  	VOLUME_NAME_DOS  = 0x0
   333  	VOLUME_NAME_GUID = 0x1
   334  	VOLUME_NAME_NONE = 0x4
   335  	VOLUME_NAME_NT   = 0x2
   336  )
   337  
   338  //sys	GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW
   339  
   340  func LoadGetFinalPathNameByHandle() error {
   341  	return procGetFinalPathNameByHandleW.Find()
   342  }
   343  
   344  //sys	CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
   345  //sys	DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
   346  
   347  //sys	RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036