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