github.com/octohelm/cuemod@v0.9.4/internal/internals/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 int64 133 LastAccessTime int64 134 LastWriteTime int64 135 ChangedTime int64 136 FileAttributes uint32 137 138 // Pad out to 8-byte alignment. 139 // 140 // Without this padding, TestChmod fails due to an argument validation error 141 // in SetFileInformationByHandle on windows/386. 142 // 143 // https://learn.microsoft.com/en-us/cpp/build/reference/zp-struct-member-alignment?view=msvc-170 144 // says that “The C/C++ headers in the Windows SDK assume the platform's 145 // default alignment is used.” What we see here is padding rather than 146 // alignment, but maybe it is related. 147 _ uint32 148 } 149 150 const ( 151 IfOperStatusUp = 1 152 IfOperStatusDown = 2 153 IfOperStatusTesting = 3 154 IfOperStatusUnknown = 4 155 IfOperStatusDormant = 5 156 IfOperStatusNotPresent = 6 157 IfOperStatusLowerLayerDown = 7 158 ) 159 160 //sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses 161 //sys GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW 162 //sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW 163 //sys GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) = kernel32.GetModuleFileNameW 164 //sys SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf unsafe.Pointer, bufsize uint32) (err error) = kernel32.SetFileInformationByHandle 165 //sys VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQuery 166 //sys GetTempPath2(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPath2W 167 168 const ( 169 // flags for CreateToolhelp32Snapshot 170 TH32CS_SNAPMODULE = 0x08 171 TH32CS_SNAPMODULE32 = 0x10 172 ) 173 174 const MAX_MODULE_NAME32 = 255 175 176 type ModuleEntry32 struct { 177 Size uint32 178 ModuleID uint32 179 ProcessID uint32 180 GlblcntUsage uint32 181 ProccntUsage uint32 182 ModBaseAddr uintptr 183 ModBaseSize uint32 184 ModuleHandle syscall.Handle 185 Module [MAX_MODULE_NAME32 + 1]uint16 186 ExePath [syscall.MAX_PATH]uint16 187 } 188 189 const SizeofModuleEntry32 = unsafe.Sizeof(ModuleEntry32{}) 190 191 //sys Module32First(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW 192 //sys Module32Next(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32NextW 193 194 const ( 195 WSA_FLAG_OVERLAPPED = 0x01 196 WSA_FLAG_NO_HANDLE_INHERIT = 0x80 197 198 WSAEMSGSIZE syscall.Errno = 10040 199 200 MSG_PEEK = 0x2 201 MSG_TRUNC = 0x0100 202 MSG_CTRUNC = 0x0200 203 204 socket_error = uintptr(^uint32(0)) 205 ) 206 207 var WSAID_WSASENDMSG = syscall.GUID{ 208 Data1: 0xa441e712, 209 Data2: 0x754f, 210 Data3: 0x43ca, 211 Data4: [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d}, 212 } 213 214 var WSAID_WSARECVMSG = syscall.GUID{ 215 Data1: 0xf689d7c8, 216 Data2: 0x6f1f, 217 Data3: 0x436b, 218 Data4: [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22}, 219 } 220 221 var sendRecvMsgFunc struct { 222 once sync.Once 223 sendAddr uintptr 224 recvAddr uintptr 225 err error 226 } 227 228 type WSAMsg struct { 229 Name syscall.Pointer 230 Namelen int32 231 Buffers *syscall.WSABuf 232 BufferCount uint32 233 Control syscall.WSABuf 234 Flags uint32 235 } 236 237 //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 238 239 func loadWSASendRecvMsg() error { 240 sendRecvMsgFunc.once.Do(func() { 241 var s syscall.Handle 242 s, sendRecvMsgFunc.err = syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) 243 if sendRecvMsgFunc.err != nil { 244 return 245 } 246 defer syscall.CloseHandle(s) 247 var n uint32 248 sendRecvMsgFunc.err = syscall.WSAIoctl(s, 249 syscall.SIO_GET_EXTENSION_FUNCTION_POINTER, 250 (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)), 251 uint32(unsafe.Sizeof(WSAID_WSARECVMSG)), 252 (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)), 253 uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)), 254 &n, nil, 0) 255 if sendRecvMsgFunc.err != nil { 256 return 257 } 258 sendRecvMsgFunc.err = syscall.WSAIoctl(s, 259 syscall.SIO_GET_EXTENSION_FUNCTION_POINTER, 260 (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)), 261 uint32(unsafe.Sizeof(WSAID_WSASENDMSG)), 262 (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)), 263 uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)), 264 &n, nil, 0) 265 }) 266 return sendRecvMsgFunc.err 267 } 268 269 func WSASendMsg(fd syscall.Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *syscall.Overlapped, croutine *byte) error { 270 err := loadWSASendRecvMsg() 271 if err != nil { 272 return err 273 } 274 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))) 275 if r1 == socket_error { 276 if e1 != 0 { 277 err = errnoErr(e1) 278 } else { 279 err = syscall.EINVAL 280 } 281 } 282 return err 283 } 284 285 func WSARecvMsg(fd syscall.Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *syscall.Overlapped, croutine *byte) error { 286 err := loadWSASendRecvMsg() 287 if err != nil { 288 return err 289 } 290 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) 291 if r1 == socket_error { 292 if e1 != 0 { 293 err = errnoErr(e1) 294 } else { 295 err = syscall.EINVAL 296 } 297 } 298 return err 299 } 300 301 const ( 302 ComputerNameNetBIOS = 0 303 ComputerNameDnsHostname = 1 304 ComputerNameDnsDomain = 2 305 ComputerNameDnsFullyQualified = 3 306 ComputerNamePhysicalNetBIOS = 4 307 ComputerNamePhysicalDnsHostname = 5 308 ComputerNamePhysicalDnsDomain = 6 309 ComputerNamePhysicalDnsFullyQualified = 7 310 ComputerNameMax = 8 311 312 MOVEFILE_REPLACE_EXISTING = 0x1 313 MOVEFILE_COPY_ALLOWED = 0x2 314 MOVEFILE_DELAY_UNTIL_REBOOT = 0x4 315 MOVEFILE_WRITE_THROUGH = 0x8 316 MOVEFILE_CREATE_HARDLINK = 0x10 317 MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20 318 ) 319 320 func Rename(oldpath, newpath string) error { 321 from, err := syscall.UTF16PtrFromString(oldpath) 322 if err != nil { 323 return err 324 } 325 to, err := syscall.UTF16PtrFromString(newpath) 326 if err != nil { 327 return err 328 } 329 return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING) 330 } 331 332 //sys LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.LockFileEx 333 //sys UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.UnlockFileEx 334 335 const ( 336 LOCKFILE_FAIL_IMMEDIATELY = 0x00000001 337 LOCKFILE_EXCLUSIVE_LOCK = 0x00000002 338 ) 339 340 const MB_ERR_INVALID_CHARS = 8 341 342 //sys GetACP() (acp uint32) = kernel32.GetACP 343 //sys GetConsoleCP() (ccp uint32) = kernel32.GetConsoleCP 344 //sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar 345 //sys GetCurrentThread() (pseudoHandle syscall.Handle, err error) = kernel32.GetCurrentThread 346 347 // Constants from lmshare.h 348 const ( 349 STYPE_DISKTREE = 0x00 350 STYPE_TEMPORARY = 0x40000000 351 ) 352 353 type SHARE_INFO_2 struct { 354 Netname *uint16 355 Type uint32 356 Remark *uint16 357 Permissions uint32 358 MaxUses uint32 359 CurrentUses uint32 360 Path *uint16 361 Passwd *uint16 362 } 363 364 //sys NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) = netapi32.NetShareAdd 365 //sys NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) = netapi32.NetShareDel 366 367 const ( 368 FILE_NAME_NORMALIZED = 0x0 369 FILE_NAME_OPENED = 0x8 370 371 VOLUME_NAME_DOS = 0x0 372 VOLUME_NAME_GUID = 0x1 373 VOLUME_NAME_NONE = 0x4 374 VOLUME_NAME_NT = 0x2 375 ) 376 377 //sys GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW 378 379 func ErrorLoadingGetTempPath2() error { 380 return procGetTempPath2W.Find() 381 } 382 383 //sys CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock 384 //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock 385 //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW 386 387 //sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng 388 389 type FILE_ID_BOTH_DIR_INFO struct { 390 NextEntryOffset uint32 391 FileIndex uint32 392 CreationTime syscall.Filetime 393 LastAccessTime syscall.Filetime 394 LastWriteTime syscall.Filetime 395 ChangeTime syscall.Filetime 396 EndOfFile uint64 397 AllocationSize uint64 398 FileAttributes uint32 399 FileNameLength uint32 400 EaSize uint32 401 ShortNameLength uint32 402 ShortName [12]uint16 403 FileID uint64 404 FileName [1]uint16 405 } 406 407 type FILE_FULL_DIR_INFO struct { 408 NextEntryOffset uint32 409 FileIndex uint32 410 CreationTime syscall.Filetime 411 LastAccessTime syscall.Filetime 412 LastWriteTime syscall.Filetime 413 ChangeTime syscall.Filetime 414 EndOfFile uint64 415 AllocationSize uint64 416 FileAttributes uint32 417 FileNameLength uint32 418 EaSize uint32 419 FileName [1]uint16 420 } 421 422 //sys GetVolumeInformationByHandle(file syscall.Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationByHandleW 423 //sys GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) = GetVolumeNameForVolumeMountPointW 424 425 //sys RtlLookupFunctionEntry(pc uintptr, baseAddress *uintptr, table *byte) (ret uintptr) = kernel32.RtlLookupFunctionEntry 426 //sys RtlVirtualUnwind(handlerType uint32, baseAddress uintptr, pc uintptr, entry uintptr, ctxt uintptr, data *uintptr, frame *uintptr, ctxptrs *byte) (ret uintptr) = kernel32.RtlVirtualUnwind 427 428 type SERVICE_STATUS struct { 429 ServiceType uint32 430 CurrentState uint32 431 ControlsAccepted uint32 432 Win32ExitCode uint32 433 ServiceSpecificExitCode uint32 434 CheckPoint uint32 435 WaitHint uint32 436 } 437 438 const ( 439 SERVICE_RUNNING = 4 440 SERVICE_QUERY_STATUS = 4 441 ) 442 443 //sys OpenService(mgr syscall.Handle, serviceName *uint16, access uint32) (handle syscall.Handle, err error) = advapi32.OpenServiceW 444 //sys QueryServiceStatus(hService syscall.Handle, lpServiceStatus *SERVICE_STATUS) (err error) = advapi32.QueryServiceStatus 445 //sys OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle syscall.Handle, err error) [failretval==0] = advapi32.OpenSCManagerW