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