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