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