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