Source file src/internal/syscall/windows/syscall_windows.go

     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
   446  

View as plain text