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