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